Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: ignore DeadlineExceeded error correctly on bootstrap
The problem was that gRPC method `status.Code(err)` doesn't unwrap errors, while Talos client returns errors wrapped with `multierror.Error` and `fmt.Errrorf`, so `status.Code` doesn't return error code correctly. Fix that by introducing our own client method which correctly goes over the chain of wrapped errors. Signed-off-by: Andrey Smirnov <smirnov.andrey@gmail.com> (cherry picked from commit 10c2875)
- Loading branch information
Showing
15 changed files
with
122 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// This Source Code Form is subject to the terms of the Mozilla Public | ||
// License, v. 2.0. If a copy of the MPL was not distributed with this | ||
// file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
|
||
package client | ||
|
||
import ( | ||
"errors" | ||
|
||
"google.golang.org/grpc/codes" | ||
"google.golang.org/grpc/status" | ||
) | ||
|
||
// StatusCode returns the Code of the error if it is a Status error, codes.OK if err | ||
// is nil, or codes.Unknown otherwise correctly unwrapping wrapped errors. | ||
// | ||
// StatusCode is mostly equivalent to grpc `status.Code` method, but it correctly unwraps wrapped errors | ||
// including `multierror.Error` used when parsing multi-node responses. | ||
func StatusCode(err error) codes.Code { | ||
type grpcStatus interface { | ||
GRPCStatus() *status.Status | ||
} | ||
|
||
// Don't use FromError to avoid allocation of OK status. | ||
if err == nil { | ||
return codes.OK | ||
} | ||
|
||
var se grpcStatus | ||
|
||
if errors.As(err, &se) { | ||
return se.GRPCStatus().Code() | ||
} | ||
|
||
return codes.Unknown | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// This Source Code Form is subject to the terms of the Mozilla Public | ||
// License, v. 2.0. If a copy of the MPL was not distributed with this | ||
// file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
|
||
package client_test | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/hashicorp/go-multierror" | ||
"github.com/stretchr/testify/assert" | ||
"google.golang.org/grpc/codes" | ||
"google.golang.org/grpc/status" | ||
|
||
"github.com/talos-systems/talos/pkg/machinery/client" | ||
) | ||
|
||
func TestStatusCode(t *testing.T) { | ||
for _, tt := range []struct { | ||
name string | ||
err error | ||
code codes.Code | ||
}{ | ||
{ | ||
name: "nil", | ||
err: nil, | ||
code: codes.OK, | ||
}, | ||
{ | ||
name: "not status", | ||
err: errors.New("some error"), | ||
code: codes.Unknown, | ||
}, | ||
{ | ||
name: "status", | ||
err: status.Error(codes.AlreadyExists, "file already exists"), | ||
code: codes.AlreadyExists, | ||
}, | ||
{ | ||
name: "status wrapped", | ||
err: multierror.Append(nil, status.Error(codes.AlreadyExists, "file already exists")).ErrorOrNil(), | ||
code: codes.AlreadyExists, | ||
}, | ||
{ | ||
name: "multiple wrapped", | ||
err: multierror.Append(nil, status.Error(codes.FailedPrecondition, "can't be zero"), status.Error(codes.AlreadyExists, "file already exists")).ErrorOrNil(), | ||
code: codes.FailedPrecondition, | ||
}, | ||
{ | ||
name: "double wrapped", | ||
err: multierror.Append(nil, fmt.Errorf("127.0.0.1: %w", status.Error(codes.AlreadyExists, "file already exists"))).ErrorOrNil(), | ||
code: codes.AlreadyExists, | ||
}, | ||
} { | ||
tt := tt | ||
|
||
t.Run(tt.name, func(t *testing.T) { | ||
assert.Equal(t, client.StatusCode(tt.err), tt.code) | ||
}) | ||
} | ||
} |