mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-10 20:42:26 +00:00
Add support for CRI ErrSignatureValidationFailed
This allows container runtimes to propagate an image signature verification error through the CRI and display that to the end user during image pull. There is no other behavioral difference compared to a regular image pull failure. Signed-off-by: Sascha Grunert <sgrunert@redhat.com>
This commit is contained in:
parent
19830bf51b
commit
63b69dd50c
@ -29,6 +29,7 @@ import (
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
|
||||
crierrors "k8s.io/cri-api/pkg/errors"
|
||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
||||
"k8s.io/kubernetes/pkg/kubelet/events"
|
||||
)
|
||||
@ -158,14 +159,8 @@ func (m *imageManager) EnsureImageExists(ctx context.Context, pod *v1.Pod, conta
|
||||
m.logIt(ref, v1.EventTypeWarning, events.FailedToPullImage, logPrefix, fmt.Sprintf("Failed to pull image %q: %v", container.Image, imagePullResult.err), klog.Warning)
|
||||
m.backOff.Next(backOffKey, m.backOff.Clock.Now())
|
||||
|
||||
// Error assertions via errors.Is is not supported by gRPC (remote runtime) errors right now.
|
||||
// See https://github.com/grpc/grpc-go/issues/3616
|
||||
if imagePullResult.err.Error() == ErrRegistryUnavailable.Error() {
|
||||
msg := fmt.Sprintf("image pull failed for %s because the registry is unavailable.", container.Image)
|
||||
return "", msg, imagePullResult.err
|
||||
}
|
||||
|
||||
return "", imagePullResult.err.Error(), ErrImagePull
|
||||
msg, err := evalCRIPullErr(container, imagePullResult.err)
|
||||
return "", msg, err
|
||||
}
|
||||
m.podPullingTimeRecorder.RecordImageFinishedPulling(pod.UID)
|
||||
m.logIt(ref, v1.EventTypeNormal, events.PulledImage, logPrefix, fmt.Sprintf("Successfully pulled image %q in %v (%v including waiting)",
|
||||
@ -174,6 +169,23 @@ func (m *imageManager) EnsureImageExists(ctx context.Context, pod *v1.Pod, conta
|
||||
return imagePullResult.imageRef, "", nil
|
||||
}
|
||||
|
||||
func evalCRIPullErr(container *v1.Container, err error) (errMsg string, errRes error) {
|
||||
// Error assertions via errors.Is is not supported by gRPC (remote runtime) errors right now.
|
||||
// See https://github.com/grpc/grpc-go/issues/3616
|
||||
if err.Error() == crierrors.ErrRegistryUnavailable.Error() {
|
||||
errMsg = fmt.Sprintf("image pull failed for %s because the registry is unavailable.", container.Image)
|
||||
return errMsg, crierrors.ErrRegistryUnavailable
|
||||
}
|
||||
|
||||
if err.Error() == crierrors.ErrSignatureValidationFailed.Error() {
|
||||
errMsg = fmt.Sprintf("image pull failed for %s because the signature validation failed.", container.Image)
|
||||
return errMsg, crierrors.ErrSignatureValidationFailed
|
||||
}
|
||||
|
||||
// Fallback for no specific error
|
||||
return err.Error(), ErrImagePull
|
||||
}
|
||||
|
||||
// applyDefaultImageTag parses a docker image string, if it doesn't contain any tag or digest,
|
||||
// a default tag will be applied.
|
||||
func applyDefaultImageTag(image string) (string, error) {
|
||||
|
@ -29,6 +29,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/tools/record"
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
crierrors "k8s.io/cri-api/pkg/errors"
|
||||
. "k8s.io/kubernetes/pkg/kubelet/container"
|
||||
ctest "k8s.io/kubernetes/pkg/kubelet/container/testing"
|
||||
testingclock "k8s.io/utils/clock/testing"
|
||||
@ -413,3 +414,46 @@ func TestMaxParallelImagePullsLimit(t *testing.T) {
|
||||
wg.Wait()
|
||||
fakeRuntime.AssertCallCounts("PullImage", 7)
|
||||
}
|
||||
|
||||
func TestEvalCRIPullErr(t *testing.T) {
|
||||
t.Parallel()
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
input error
|
||||
assert func(string, error)
|
||||
}{
|
||||
{
|
||||
name: "fallback error",
|
||||
input: errors.New("test"),
|
||||
assert: func(msg string, err error) {
|
||||
assert.ErrorIs(t, err, ErrImagePull)
|
||||
assert.Contains(t, msg, "test")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "registry is unavailable",
|
||||
input: crierrors.ErrRegistryUnavailable,
|
||||
assert: func(msg string, err error) {
|
||||
assert.ErrorIs(t, err, crierrors.ErrRegistryUnavailable)
|
||||
assert.Contains(t, msg, "registry is unavailable")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "signature is invalid",
|
||||
input: crierrors.ErrSignatureValidationFailed,
|
||||
assert: func(msg string, err error) {
|
||||
assert.ErrorIs(t, err, crierrors.ErrSignatureValidationFailed)
|
||||
assert.Contains(t, msg, "signature validation failed")
|
||||
},
|
||||
},
|
||||
} {
|
||||
testInput := tc.input
|
||||
testAssert := tc.assert
|
||||
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
msg, err := evalCRIPullErr(&v1.Container{}, testInput)
|
||||
testAssert(msg, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -37,9 +37,6 @@ var (
|
||||
// ErrImageNeverPull - Required Image is absent on host and PullPolicy is NeverPullImage
|
||||
ErrImageNeverPull = errors.New("ErrImageNeverPull")
|
||||
|
||||
// ErrRegistryUnavailable - Get http error when pulling image from registry
|
||||
ErrRegistryUnavailable = errors.New("RegistryUnavailable")
|
||||
|
||||
// ErrInvalidImageName - Unable to parse the image name.
|
||||
ErrInvalidImageName = errors.New("InvalidImageName")
|
||||
)
|
||||
|
@ -17,10 +17,20 @@ limitations under the License.
|
||||
package errors
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrRegistryUnavailable - Get http error on the PullImage RPC call.
|
||||
ErrRegistryUnavailable = errors.New("RegistryUnavailable")
|
||||
|
||||
// ErrSignatureValidationFailed - Unable to validate the image signature on the PullImage RPC call.
|
||||
ErrSignatureValidationFailed = errors.New("SignatureValidationFailed")
|
||||
)
|
||||
|
||||
// IsNotFound returns a boolean indicating whether the error
|
||||
// is grpc not found error.
|
||||
// See https://github.com/grpc/grpc/blob/master/doc/statuscodes.md
|
||||
|
Loading…
Reference in New Issue
Block a user