mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-29 14:37:00 +00:00
Filtered out unfriendly error from docker when registry is not reachable(code: 502, 503, 504)
This commit is contained in:
parent
bbea2863c2
commit
636b40ffa1
@ -19,6 +19,7 @@ package dockertools
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -31,6 +32,7 @@ import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/types"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
utilerrors "github.com/GoogleCloudPlatform/kubernetes/pkg/util/errors"
|
||||
"github.com/docker/docker/pkg/jsonmessage"
|
||||
"github.com/docker/docker/pkg/parsers"
|
||||
docker "github.com/fsouza/go-dockerclient"
|
||||
"github.com/golang/glog"
|
||||
@ -113,6 +115,22 @@ func parseImageName(image string) (string, string) {
|
||||
return parsers.ParseRepositoryTag(image)
|
||||
}
|
||||
|
||||
func filterHTTPError(err error, image string) error {
|
||||
// docker/docker/pull/11314 prints detailed error info for docker pull.
|
||||
// When it hits 502, it returns a verbose html output including an inline svg,
|
||||
// which makes the output of kubectl get pods much harder to parse.
|
||||
// Here converts such verbose output to a concise one.
|
||||
jerr, ok := err.(*jsonmessage.JSONError)
|
||||
if ok && (jerr.Code == http.StatusBadGateway ||
|
||||
jerr.Code == http.StatusServiceUnavailable ||
|
||||
jerr.Code == http.StatusGatewayTimeout) {
|
||||
glog.V(2).Infof("Pulling image %q failed: %v", image, err)
|
||||
return fmt.Errorf("image pull failed for %s because the registry is temporarily unavailbe.", image)
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
func (p dockerPuller) Pull(image string, secrets []api.Secret) error {
|
||||
repoToPull, tag := parseImageName(image)
|
||||
|
||||
@ -149,7 +167,7 @@ func (p dockerPuller) Pull(image string, secrets []api.Secret) error {
|
||||
return fmt.Errorf("image pull failed for %s, this may be because there are no credentials on this request. details: (%v)", image, err)
|
||||
}
|
||||
|
||||
return err
|
||||
return filterHTTPError(err, image)
|
||||
}
|
||||
|
||||
var pullErrs []error
|
||||
@ -160,7 +178,7 @@ func (p dockerPuller) Pull(image string, secrets []api.Secret) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
pullErrs = append(pullErrs, err)
|
||||
pullErrs = append(pullErrs, filterHTTPError(err, image))
|
||||
}
|
||||
|
||||
return utilerrors.NewAggregate(pullErrs)
|
||||
|
@ -22,6 +22,7 @@ import (
|
||||
"hash/adler32"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
@ -31,6 +32,7 @@ import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/network"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/types"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
"github.com/docker/docker/pkg/jsonmessage"
|
||||
docker "github.com/fsouza/go-dockerclient"
|
||||
)
|
||||
|
||||
@ -238,6 +240,40 @@ func TestPullWithNoSecrets(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPullWithJSONError(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
imageName string
|
||||
err error
|
||||
expectedError string
|
||||
}{
|
||||
"Json error": {
|
||||
"ubuntu",
|
||||
&jsonmessage.JSONError{Code: 50, Message: "Json error"},
|
||||
"Json error",
|
||||
},
|
||||
"Bad gateway": {
|
||||
"ubuntu",
|
||||
&jsonmessage.JSONError{Code: 502, Message: "<!doctype html>\n<html class=\"no-js\" lang=\"\">\n <head>\n </head>\n <body>\n <h1>Oops, there was an error!</h1>\n <p>We have been contacted of this error, feel free to check out <a href=\"http://status.docker.com/\">status.docker.com</a>\n to see if there is a bigger issue.</p>\n\n </body>\n</html>"},
|
||||
"because the registry is temporarily unavailbe",
|
||||
},
|
||||
}
|
||||
for i, test := range tests {
|
||||
fakeKeyring := &credentialprovider.FakeKeyring{}
|
||||
fakeClient := &FakeDockerClient{
|
||||
Errors: map[string]error{"pull": test.err},
|
||||
}
|
||||
puller := &dockerPuller{
|
||||
client: fakeClient,
|
||||
keyring: fakeKeyring,
|
||||
}
|
||||
err := puller.Pull(test.imageName, []api.Secret{})
|
||||
if err == nil || !strings.Contains(err.Error(), test.expectedError) {
|
||||
t.Errorf("%d: expect error %s, got : %s", i, test.expectedError, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPullWithSecrets(t *testing.T) {
|
||||
// auth value is equivalent to: "username":"passed-user","password":"passed-password"
|
||||
dockerCfg := map[string]map[string]string{"index.docker.io/v1/": {"email": "passed-email", "auth": "cGFzc2VkLXVzZXI6cGFzc2VkLXBhc3N3b3Jk"}}
|
||||
|
Loading…
Reference in New Issue
Block a user