// TODO(yifan): This is very racy, inefficient, and unsafe, we need to provide // different namespaces. See: https://github.com/coreos/rkt/issues/836. func (r *Runtime) writeDockerAuthConfig(image string, credsSlice []credentialprovider.LazyAuthConfiguration, userConfigDir string) error { if len(credsSlice) == 0 { return nil } creds := dockertypes.AuthConfig{} // TODO handle multiple creds if len(credsSlice) >= 1 { creds = credentialprovider.LazyProvide(credsSlice[0]) } registry := "index.docker.io" // Image spec: [<registry>/]<repository>/<image>[:<version] explicitRegistry := (strings.Count(image, "/") == 2) if explicitRegistry { registry = strings.Split(image, "/")[0] } authDir := filepath.Join(userConfigDir, "auth.d") if _, err := os.Stat(authDir); os.IsNotExist(err) { if err := os.MkdirAll(authDir, 0600); err != nil { glog.Errorf("rkt: Cannot create auth dir: %v", err) return err } } config := fmt.Sprintf(dockerAuthTemplate, registry, creds.Username, creds.Password) if err := ioutil.WriteFile(path.Join(authDir, registry+".json"), []byte(config), 0600); err != nil { glog.Errorf("rkt: Cannot write docker auth config file: %v", err) return err } return nil }
func (p dockerPuller) Pull(image string, secrets []api.Secret) error { // If no tag was specified, use the default "latest". imageID, tag, err := parsers.ParseImageName(image) if err != nil { return err } keyring, err := credentialprovider.MakeDockerKeyring(secrets, p.keyring) if err != nil { return err } opts := dockertypes.ImagePullOptions{ Tag: tag, } creds, haveCredentials := keyring.Lookup(imageID) if !haveCredentials { glog.V(1).Infof("Pulling image %s without credentials", image) err := p.client.PullImage(imageID, dockertypes.AuthConfig{}, opts) if err == nil { // Sometimes PullImage failed with no error returned. exist, ierr := p.IsImagePresent(image) if ierr != nil { glog.Warningf("Failed to inspect image %s: %v", image, ierr) } if !exist { return fmt.Errorf("image pull failed for unknown error") } return nil } // Image spec: [<registry>/]<repository>/<image>[:<version] so we count '/' explicitRegistry := (strings.Count(image, "/") == 2) // Hack, look for a private registry, and decorate the error with the lack of // credentials. This is heuristic, and really probably could be done better // by talking to the registry API directly from the kubelet here. if explicitRegistry { return fmt.Errorf("image pull failed for %s, this may be because there are no credentials on this request. details: (%v)", image, err) } return filterHTTPError(err, image) } var pullErrs []error for _, currentCreds := range creds { err = p.client.PullImage(imageID, credentialprovider.LazyProvide(currentCreds), opts) // If there was no error, return success if err == nil { return nil } pullErrs = append(pullErrs, filterHTTPError(err, image)) } return utilerrors.NewAggregate(pullErrs) }
// PullImage pulls an image from the network to local storage using the supplied // secrets if necessary. // TODO: pull image with qps and burst, ref https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/dockertools/docker.go#L120 func (m *kubeGenericRuntimeManager) PullImage(image kubecontainer.ImageSpec, pullSecrets []api.Secret) error { img := image.Image repoToPull, _, _, err := parsers.ParseImageName(img) if err != nil { return err } keyring, err := credentialprovider.MakeDockerKeyring(pullSecrets, m.keyring) if err != nil { return err } imgSpec := &runtimeApi.ImageSpec{Image: &img} creds, withCredentials := keyring.Lookup(repoToPull) if !withCredentials { glog.V(3).Infof("Pulling image %q without credentials", img) err = m.imageService.PullImage(imgSpec, nil) if err != nil { glog.Errorf("Pull image %q failed: %v", img, err) return err } return nil } var pullErrs []error for _, currentCreds := range creds { authConfig := credentialprovider.LazyProvide(currentCreds) auth := &runtimeApi.AuthConfig{ Username: &authConfig.Username, Password: &authConfig.Password, Auth: &authConfig.Auth, ServerAddress: &authConfig.ServerAddress, IdentityToken: &authConfig.IdentityToken, RegistryToken: &authConfig.RegistryToken, } err = m.imageService.PullImage(imgSpec, auth) // If there was no error, return success if err == nil { return nil } pullErrs = append(pullErrs, err) } return utilerrors.NewAggregate(pullErrs) }