Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Raft pre-vote extension implementation #530

Merged
merged 91 commits into from
Jun 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
987cfd2
prevote initial implementation
dhiaayachi Nov 8, 2022
f1ed619
add config and relevant tests
dhiaayachi Nov 9, 2022
c57bed8
remove extra comments, fix a case where newer term is discovered for …
dhiaayachi Nov 9, 2022
3082935
fix to reset timeout after pre-vote and fix split vote (pre-vote,vote…
dhiaayachi Nov 10, 2022
2c44c94
fix a case where granted votes and prevotes don't reach quorum but th…
dhiaayachi Nov 14, 2022
baf623c
add submodule and first iteration of multi-version tests
dhiaayachi Jun 6, 2023
22b88e4
refactor test
dhiaayachi Jun 7, 2023
0882d3b
clean up node init
dhiaayachi Jun 7, 2023
14dfa68
clean up leader rolling upgrade
dhiaayachi Jun 8, 2023
a617c6d
fix use of deprecate Leader method
dhiaayachi Jun 8, 2023
60f3232
extract cluster package
dhiaayachi Jun 9, 2023
16eebcd
export cluster Type
dhiaayachi Jun 9, 2023
3e9efaf
clean up tests and add test utils
dhiaayachi Jun 9, 2023
8b56ef3
rename package to raftlatest
dhiaayachi Jun 9, 2023
2e8a26a
remove submodule
dhiaayachi Jun 9, 2023
01b88ad
new submodule
dhiaayachi Jun 9, 2023
a7aeffa
fix go.mod
dhiaayachi Jun 9, 2023
8ade0de
change inmemConfig to be not exported
dhiaayachi Jun 9, 2023
164e0c9
remove unused func
dhiaayachi Jun 9, 2023
6b0d70d
add replace rolling upgrade tests
dhiaayachi Jun 26, 2023
89da642
rename raft-latest to raft-previous
dhiaayachi Jun 26, 2023
7cde48c
rename raft-latest to raft-previous submodule
dhiaayachi Jun 26, 2023
9b03730
fix submodule
dhiaayachi Jun 26, 2023
0c3c507
remove printf
dhiaayachi Jun 26, 2023
b3dec1b
use same name for recycled servers, add other leave scenarios
dhiaayachi Jun 27, 2023
02e042f
prevote initial implementation
dhiaayachi Nov 8, 2022
a359f5c
add config and relevant tests
dhiaayachi Nov 9, 2022
e0c539d
remove extra comments, fix a case where newer term is discovered for …
dhiaayachi Nov 9, 2022
cfa7e87
fix to reset timeout after pre-vote and fix split vote (pre-vote,vote…
dhiaayachi Nov 10, 2022
2dad2f3
write upgrade tests that include prevotes
dhiaayachi Nov 14, 2022
2b09f8c
add more test cases
dhiaayachi Aug 22, 2023
785b127
fix submodule version
dhiaayachi Aug 22, 2023
63a9333
Merge branch 'main' into raft-pre-vote
dhiaayachi Oct 16, 2023
0b1811d
Merge remote-tracking branch 'origin/raft-pre-vote' into raft-pre-vote
dhiaayachi Oct 16, 2023
1b18a66
Merge branch 'main' into raft-pre-vote
dhiaayachi Dec 22, 2023
ea82333
go mod tidy
dhiaayachi Dec 22, 2023
8786e2a
update pervious version to v1.6.0
dhiaayachi Dec 22, 2023
16a8c76
fix merge duplication
dhiaayachi Dec 22, 2023
ae369f3
add submodule and first iteration of multi-version tests
dhiaayachi Jun 6, 2023
4c678d8
refactor test
dhiaayachi Jun 7, 2023
f83d298
clean up node init
dhiaayachi Jun 7, 2023
fafbf06
clean up leader rolling upgrade
dhiaayachi Jun 8, 2023
80e46f0
fix use of deprecate Leader method
dhiaayachi Jun 8, 2023
bb62335
extract cluster package
dhiaayachi Jun 9, 2023
9ed608a
export cluster Type
dhiaayachi Jun 9, 2023
4dcdf1d
clean up tests and add test utils
dhiaayachi Jun 9, 2023
475d620
rename package to raftlatest
dhiaayachi Jun 9, 2023
2bad938
remove submodule
dhiaayachi Jun 9, 2023
b3970e0
new submodule
dhiaayachi Jun 9, 2023
0a2e3b5
fix go.mod
dhiaayachi Jun 9, 2023
e926022
change inmemConfig to be not exported
dhiaayachi Jun 9, 2023
74e7f53
remove unused func
dhiaayachi Jun 9, 2023
afca282
add replace rolling upgrade tests
dhiaayachi Jun 26, 2023
34b71eb
rename raft-latest to raft-previous
dhiaayachi Jun 26, 2023
2988d07
rename raft-latest to raft-previous submodule
dhiaayachi Jun 26, 2023
e9fcf37
fix submodule
dhiaayachi Jun 26, 2023
07bd0e2
remove printf
dhiaayachi Jun 26, 2023
95e17a0
use same name for recycled servers, add other leave scenarios
dhiaayachi Jun 27, 2023
104ceaa
prevote initial implementation
dhiaayachi Nov 8, 2022
faa005e
add config and relevant tests
dhiaayachi Nov 9, 2022
d15db63
remove extra comments, fix a case where newer term is discovered for …
dhiaayachi Nov 9, 2022
e7e4476
fix to reset timeout after pre-vote and fix split vote (pre-vote,vote…
dhiaayachi Nov 10, 2022
6065328
write upgrade tests that include prevotes
dhiaayachi Nov 14, 2022
257ba38
add more test cases
dhiaayachi Aug 22, 2023
12a2bf1
fix submodule version
dhiaayachi Aug 22, 2023
3c6af46
prevote initial implementation
dhiaayachi Nov 8, 2022
989ca74
add config and relevant tests
dhiaayachi Nov 9, 2022
eba1435
remove extra comments, fix a case where newer term is discovered for …
dhiaayachi Nov 9, 2022
348e418
fix to reset timeout after pre-vote and fix split vote (pre-vote,vote…
dhiaayachi Nov 10, 2022
f4e3442
fix a case where granted votes and prevotes don't reach quorum but th…
dhiaayachi Nov 14, 2022
6744aa7
go mod tidy
dhiaayachi Dec 22, 2023
89a5e17
update pervious version to v1.6.0
dhiaayachi Dec 22, 2023
b27f8dd
fix merge duplication
dhiaayachi Dec 22, 2023
1d84a92
fix rebase issues
dhiaayachi Mar 25, 2024
e8a78ba
use a different RPC command for prevote.
dhiaayachi Mar 25, 2024
62bcfe7
fix prevote tests and add rollback tests
dhiaayachi Mar 25, 2024
97f6bd4
add a partitioned node prevote test
dhiaayachi Mar 25, 2024
d4cb80f
Merge remote-tracking branch 'origin/raft-pre-vote' into raft-pre-vote
dhiaayachi Mar 25, 2024
4e3bb65
remove server from config before shutting down, fix raft submodule
dhiaayachi Mar 25, 2024
9ce972d
remove extra comment
dhiaayachi Mar 26, 2024
36690e5
change `inmemConfig` to accept testing.TB
dhiaayachi Mar 26, 2024
43974d2
remove stray comment
dhiaayachi Mar 26, 2024
7543a3d
fix comments and remove extra fields
dhiaayachi Mar 26, 2024
de78bf8
remove duplicate var
dhiaayachi Mar 26, 2024
921be2d
remove leader transfer from pre-vote path, fix logs and comments.
dhiaayachi Mar 28, 2024
4f6fc13
make pre-vote enabled by default
dhiaayachi Mar 28, 2024
1912201
remove `Candidate` field from pre-vote request
dhiaayachi Apr 2, 2024
27a2e7d
add warning when transport don't support prevote
dhiaayachi Apr 8, 2024
ddcbc50
panic if transport is not supported in preElectSelf.
dhiaayachi Apr 8, 2024
083b811
Fix comments and log string
dhiaayachi May 29, 2024
d962c24
Fix to log the right number for votesNeeded, added preVoteRefusedVote…
dhiaayachi May 29, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,10 @@ type Raft struct {

// mainThreadSaturation measures the saturation of the main raft goroutine.
mainThreadSaturation *saturationMetric

// preVoteDisabled control if the pre-vote feature is activated,
// prevote feature is disabled if set to true.
preVoteDisabled bool
}

// BootstrapCluster initializes a server's storage with the given cluster
Expand Down Expand Up @@ -531,6 +535,7 @@ func NewRaft(conf *Config, fsm FSM, logs LogStore, stable StableStore, snaps Sna
applyCh = make(chan *logFuture, conf.MaxAppendEntries)
}

_, transportSupportPreVote := trans.(WithPreVote)
// Create Raft struct.
r := &Raft{
protocolVersion: protocolVersion,
Expand Down Expand Up @@ -560,6 +565,10 @@ func NewRaft(conf *Config, fsm FSM, logs LogStore, stable StableStore, snaps Sna
leaderNotifyCh: make(chan struct{}, 1),
followerNotifyCh: make(chan struct{}, 1),
mainThreadSaturation: newSaturationMetric([]string{"raft", "thread", "main", "saturation"}, 1*time.Second),
preVoteDisabled: conf.PreVoteDisabled || !transportSupportPreVote,
banks marked this conversation as resolved.
Show resolved Hide resolved
}
if !transportSupportPreVote && !conf.PreVoteDisabled {
r.logger.Warn("pre-vote is disabled because it is not supported by the Transport")
}

r.conf.Store(*conf)
Expand Down
34 changes: 34 additions & 0 deletions commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,40 @@ func (r *RequestVoteResponse) GetRPCHeader() RPCHeader {
return r.RPCHeader
}

// RequestPreVoteRequest is the command used by a candidate to ask a Raft peer
// for a vote in an election.
type RequestPreVoteRequest struct {
RPCHeader

// Provide the term and our id
Term uint64

// Used to ensure safety
LastLogIndex uint64
LastLogTerm uint64
}

// GetRPCHeader - See WithRPCHeader.
func (r *RequestPreVoteRequest) GetRPCHeader() RPCHeader {
return r.RPCHeader
}

// RequestPreVoteResponse is the response returned from a RequestPreVoteRequest.
type RequestPreVoteResponse struct {
RPCHeader

// Newer term if leader is out of date.
Term uint64

// Is the vote granted.
Granted bool
}

// GetRPCHeader - See WithRPCHeader.
func (r *RequestPreVoteResponse) GetRPCHeader() RPCHeader {
return r.RPCHeader
}

// InstallSnapshotRequest is the command sent to a Raft peer to bootstrap its
// log (and state machine) from a snapshot on another peer.
type InstallSnapshotRequest struct {
Expand Down
3 changes: 3 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,9 @@ type Config struct {
// raft's configuration and index values.
NoSnapshotRestoreOnStart bool

// PreVoteDisabled deactivate the pre-vote feature when set to true
PreVoteDisabled bool

// skipStartup allows NewRaft() to bypass all background work goroutines
skipStartup bool
}
Expand Down
2 changes: 1 addition & 1 deletion fuzzy/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/hashicorp/raft/fuzzy
go 1.20

require (
github.com/hashicorp/go-hclog v1.5.0
github.com/hashicorp/go-hclog v1.6.2
github.com/hashicorp/go-msgpack/v2 v2.1.1
github.com/hashicorp/raft v1.2.0
github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea
Expand Down
6 changes: 5 additions & 1 deletion fuzzy/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c=
github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
github.com/hashicorp/go-hclog v1.6.2/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI=
Expand Down Expand Up @@ -91,7 +92,10 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
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.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
Expand Down
5 changes: 5 additions & 0 deletions fuzzy/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,11 @@ func (t *transport) RequestVote(id raft.ServerID, target raft.ServerAddress, arg
return t.sendRPC(string(target), args, resp)
}

// RequestPreVote sends the appropriate RPC to the target node.
func (t *transport) RequestPreVote(id raft.ServerID, target raft.ServerAddress, args *raft.RequestPreVoteRequest, resp *raft.RequestPreVoteResponse) error {
return t.sendRPC(string(target), args, resp)
}

// InstallSnapshot is used to push a snapshot down to a follower. The data is read from
// the ReadCloser and streamed to the client.
func (t *transport) InstallSnapshot(id raft.ServerID, target raft.ServerAddress, args *raft.InstallSnapshotRequest, resp *raft.InstallSnapshotResponse, data io.Reader) error {
Expand Down
12 changes: 12 additions & 0 deletions inmem_transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,18 @@ func (i *InmemTransport) RequestVote(id ServerID, target ServerAddress, args *Re
return nil
}

func (i *InmemTransport) RequestPreVote(id ServerID, target ServerAddress, args *RequestPreVoteRequest, resp *RequestPreVoteResponse) error {
rpcResp, err := i.makeRPC(target, args, nil, i.timeout)
if err != nil {
return err
}

// Copy the result back
out := rpcResp.Response.(*RequestPreVoteResponse)
*resp = *out
return nil
}

// InstallSnapshot implements the Transport interface.
func (i *InmemTransport) InstallSnapshot(id ServerID, target ServerAddress, args *InstallSnapshotRequest, resp *InstallSnapshotResponse, data io.Reader) error {
rpcResp, err := i.makeRPC(target, args, data, 10*i.timeout)
Expand Down
13 changes: 13 additions & 0 deletions net_transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const (
rpcRequestVote
rpcInstallSnapshot
rpcTimeoutNow
rpcRequestPreVote

// DefaultTimeoutScale is the default TimeoutScale in a NetworkTransport.
DefaultTimeoutScale = 256 * 1024 // 256KB
Expand Down Expand Up @@ -470,6 +471,11 @@ func (n *NetworkTransport) RequestVote(id ServerID, target ServerAddress, args *
return n.genericRPC(id, target, rpcRequestVote, args, resp)
}

// RequestPreVote implements the Transport interface.
func (n *NetworkTransport) RequestPreVote(id ServerID, target ServerAddress, args *RequestPreVoteRequest, resp *RequestPreVoteResponse) error {
return n.genericRPC(id, target, rpcRequestPreVote, args, resp)
}

// genericRPC handles a simple request/response RPC.
func (n *NetworkTransport) genericRPC(id ServerID, target ServerAddress, rpcType uint8, args interface{}, resp interface{}) error {
// Get a conn
Expand Down Expand Up @@ -682,6 +688,13 @@ func (n *NetworkTransport) handleCommand(r *bufio.Reader, dec *codec.Decoder, en
}
rpc.Command = &req
labels = []metrics.Label{{Name: "rpcType", Value: "RequestVote"}}
case rpcRequestPreVote:
var req RequestPreVoteRequest
if err := dec.Decode(&req); err != nil {
return err
}
rpc.Command = &req
labels = []metrics.Label{{Name: "rpcType", Value: "RequestPreVote"}}
case rpcInstallSnapshot:
var req InstallSnapshotRequest
if err := dec.Decode(&req); err != nil {
Expand Down
7 changes: 4 additions & 3 deletions raft-compat/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ require github.com/stretchr/testify v1.8.4
require (
github.com/armon/go-metrics v0.4.1 // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/hashicorp/go-hclog v1.5.0 // indirect
github.com/hashicorp/go-hclog v1.6.2 // indirect
github.com/hashicorp/go-immutable-radix v1.0.0 // indirect
github.com/hashicorp/go-msgpack v0.5.5 // indirect
github.com/hashicorp/go-msgpack/v2 v2.1.1 // indirect
github.com/hashicorp/golang-lru v0.5.0 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 // indirect
golang.org/x/sys v0.13.0 // indirect
)

replace github.com/hashicorp/raft-previous-version => ./raft-previous-version
Expand All @@ -22,7 +23,7 @@ replace github.com/hashicorp/raft => ../

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/hashicorp/raft v1.2.0
github.com/hashicorp/raft v1.6.1
github.com/hashicorp/raft-previous-version v1.2.0
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
Expand Down
6 changes: 6 additions & 0 deletions raft-compat/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,14 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c=
github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
github.com/hashicorp/go-hclog v1.6.2 h1:NOtoftovWkDheyUM/8JW3QMiXyxJK3uHRK7wV04nD2I=
github.com/hashicorp/go-hclog v1.6.2/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0=
github.com/hashicorp/go-immutable-radix v1.0.0/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.1 h1:xQEY9yB2wnHitoSzk/B9UjXWRQ67QKu5AOm8aFp8N3I=
github.com/hashicorp/go-msgpack/v2 v2.1.1/go.mod h1:upybraOAblm4S7rx0+jeNy+CWWhzywQsSRV5033mMu4=
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCSnM=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
Expand Down Expand Up @@ -113,6 +117,8 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 h1:nonptSpoQ4vQjyraW20DXPAglgQfVnM9ZC6MmNLMR60=
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
Expand Down