From 05cde3e75982d9c8961ecc64c87bf2933fd92166 Mon Sep 17 00:00:00 2001 From: Antonio Murdaca Date: Mon, 10 Apr 2017 15:00:24 +0200 Subject: [PATCH] server: add auth info to image pull Fix the following upstream k8s's e2e-node test: ``` should be able to pull from private registry with secret [Conformance] ``` Signed-off-by: Antonio Murdaca --- server/image_pull.go | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/server/image_pull.go b/server/image_pull.go index 55290cd8..8790b065 100644 --- a/server/image_pull.go +++ b/server/image_pull.go @@ -1,8 +1,12 @@ package server import ( + "encoding/base64" + "strings" + "github.com/Sirupsen/logrus" "github.com/containers/image/copy" + "github.com/containers/image/types" "golang.org/x/net/context" pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime" ) @@ -17,7 +21,32 @@ func (s *Server) PullImage(ctx context.Context, req *pb.PullImageRequest) (*pb.P if img != nil { image = img.Image } + var ( + username string + password string + ) + if req.GetAuth() != nil { + username = req.GetAuth().Username + password = req.GetAuth().Password + if req.GetAuth().Auth != "" { + var err error + username, password, err = decodeDockerAuth(req.GetAuth().Auth) + if err != nil { + return nil, err + } + } + } options := ©.Options{} + // a not empty username should be sufficient to decide whether to send auth + // or not I guess + if username != "" { + options.SourceCtx = &types.SystemContext{ + DockerAuthConfig: &types.DockerAuthConfig{ + Username: username, + Password: password, + }, + } + } _, err := s.images.PullImage(s.imageContext, image, options) if err != nil { return nil, err @@ -28,3 +57,18 @@ func (s *Server) PullImage(ctx context.Context, req *pb.PullImageRequest) (*pb.P logrus.Debugf("PullImageResponse: %+v", resp) return resp, nil } + +func decodeDockerAuth(s string) (string, string, error) { + decoded, err := base64.StdEncoding.DecodeString(s) + if err != nil { + return "", "", err + } + parts := strings.SplitN(string(decoded), ":", 2) + if len(parts) != 2 { + // if it's invalid just skip, as docker does + return "", "", nil + } + user := parts[0] + password := strings.Trim(parts[1], "\x00") + return user, password, nil +}