// PullImage invokes 'rkt fetch' to download an aci. // TODO(yifan): Now we only support docker images, this should be changed // once the format of image is landed, see: // // https://github.com/GoogleCloudPlatform/kubernetes/issues/7203 // func (r *runtime) PullImage(image kubecontainer.ImageSpec, pullSecrets []api.Secret) error { img := image.Image // TODO(yifan): The credential operation is a copy from dockertools package, // Need to resolve the code duplication. repoToPull, tag := parsers.ParseRepositoryTag(img) // If no tag was specified, use the default "latest". if len(tag) == 0 { tag = "latest" } keyring, err := credentialprovider.MakeDockerKeyring(pullSecrets, r.dockerKeyring) if err != nil { return err } creds, ok := keyring.Lookup(repoToPull) if !ok { glog.V(1).Infof("Pulling image %s without credentials", img) } // Let's update a json. // TODO(yifan): Find a way to feed this to rkt. if err := r.writeDockerAuthConfig(img, creds); err != nil { return err } output, err := r.runCommand("fetch", dockerPrefix+img) if err != nil { return fmt.Errorf("rkt: Failed to fetch image: %v:", output) } return nil }
// PullImage invokes 'rkt fetch' to download an aci. // TODO(yifan): Now we only support docker images, this should be changed // once the format of image is landed, see: // // http://issue.k8s.io/7203 // func (r *runtime) PullImage(image kubecontainer.ImageSpec, pullSecrets []api.Secret) error { img := image.Image // TODO(yifan): The credential operation is a copy from dockertools package, // Need to resolve the code duplication. repoToPull, _ := parseImageName(img) keyring, err := credentialprovider.MakeDockerKeyring(pullSecrets, r.dockerKeyring) if err != nil { return err } creds, ok := keyring.Lookup(repoToPull) if !ok { glog.V(1).Infof("Pulling image %s without credentials", img) } // Let's update a json. // TODO(yifan): Find a way to feed this to rkt. if err := r.writeDockerAuthConfig(img, creds); err != nil { return err } if _, err := r.runCommand("fetch", dockerPrefix+img); err != nil { glog.Errorf("Failed to fetch: %v", err) return err } return nil }
func (p dockerPuller) Pull(image string, secrets []api.Secret) error { repoToPull, tag := parseImageName(image) // If no tag was specified, use the default "latest". if len(tag) == 0 { tag = "latest" } opts := docker.PullImageOptions{ Repository: repoToPull, Tag: tag, } keyring, err := credentialprovider.MakeDockerKeyring(secrets, p.keyring) if err != nil { return err } creds, haveCredentials := keyring.Lookup(repoToPull) if !haveCredentials { glog.V(1).Infof("Pulling image %s without credentials", image) err := p.client.PullImage(opts, docker.AuthConfiguration{}) 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(opts, currentCreds) // If there was no error, return success if err == nil { return nil } pullErrs = append(pullErrs, filterHTTPError(err, image)) } return utilerrors.NewAggregate(pullErrs) }
func (p dockerPuller) Pull(image string, secrets []api.Secret) error { // If the image contains no tag or digest, a default tag should be applied. image, err := applyDefaultImageTag(image) if err != nil { return err } keyring, err := credentialprovider.MakeDockerKeyring(secrets, p.keyring) if err != nil { return err } // The only used image pull option RegistryAuth will be set in kube_docker_client opts := dockertypes.ImagePullOptions{} creds, haveCredentials := keyring.Lookup(image) if !haveCredentials { glog.V(1).Infof("Pulling image %s without credentials", image) err := p.client.PullImage(image, 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(image, 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) }
func (s *secretCredentialStore) init() credentialprovider.DockerKeyring { s.lock.Lock() defer s.lock.Unlock() if s.keyring != nil { return s.keyring } // TODO: need a version of this that is best effort secret - otherwise one error blocks all secrets keyring, err := credentialprovider.MakeDockerKeyring(s.secrets, emptyKeyring) if err != nil { util.HandleError(fmt.Errorf("unable to create Docker registry pull credentials for secrets: %v", err)) keyring = emptyKeyring } s.keyring = keyring return keyring }
// PullImage pulls an image from the network to local storage using the supplied // secrets if necessary. func (r *runtime) PullImage(image kubecontainer.ImageSpec, pullSecrets []api.Secret) error { img := image.Image repoToPull, tag := parseImageName(img) if exist, _ := r.hyperClient.IsImagePresent(repoToPull, tag); exist { return nil } keyring, err := credentialprovider.MakeDockerKeyring(pullSecrets, r.dockerKeyring) if err != nil { return err } creds, ok := keyring.Lookup(repoToPull) if !ok || len(creds) == 0 { glog.V(4).Infof("Hyper: pulling image %s without credentials", img) } var credential string if len(creds) > 0 { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(creds[0]); err != nil { return err } credential = base64.URLEncoding.EncodeToString(buf.Bytes()) } err = r.hyperClient.PullImage(img, credential) if err != nil { return fmt.Errorf("Hyper: Failed to pull image: %v", err) } if exist, _ := r.hyperClient.IsImagePresent("haproxy", "1.4"); !exist { err = r.hyperClient.PullImage("haproxy", credential) if err != nil { return fmt.Errorf("Hyper: Failed to pull haproxy image: %v", err) } } return nil }
// PullImage invokes 'rkt fetch' to download an aci. // TODO(yifan): Now we only support docker images, this should be changed // once the format of image is landed, see: // // http://issue.k8s.io/7203 // func (r *Runtime) PullImage(image kubecontainer.ImageSpec, pullSecrets []api.Secret) error { img := image.Image // TODO(yifan): The credential operation is a copy from dockertools package, // Need to resolve the code duplication. repoToPull, _, _, err := parsers.ParseImageName(img) if err != nil { return err } keyring, err := credentialprovider.MakeDockerKeyring(pullSecrets, r.dockerKeyring) if err != nil { return err } creds, ok := keyring.Lookup(repoToPull) if !ok { glog.V(1).Infof("Pulling image %s without credentials", img) } userConfigDir, err := ioutil.TempDir("", "rktnetes-user-config-dir-") if err != nil { return fmt.Errorf("rkt: Cannot create a temporary user-config directory: %v", err) } defer os.RemoveAll(userConfigDir) config := *r.config config.UserConfigDir = userConfigDir if err := r.writeDockerAuthConfig(img, creds, userConfigDir); err != nil { return err } // Today, `--no-store` will fetch the remote image regardless of whether the content of the image // has changed or not. This causes performance downgrades when the image tag is ':latest' and // the image pull policy is 'always'. The issue is tracked in https://github.com/coreos/rkt/issues/2937. if _, err := r.cli.RunCommand(&config, "fetch", "--no-store", dockerPrefix+img); err != nil { glog.Errorf("Failed to fetch: %v", err) return err } return nil }
// PullImage invokes 'rkt fetch' to download an aci. // TODO(yifan): Now we only support docker images, this should be changed // once the format of image is landed, see: // // http://issue.k8s.io/7203 // func (r *Runtime) PullImage(image kubecontainer.ImageSpec, pullSecrets []api.Secret) error { img := image.Image // TODO(yifan): The credential operation is a copy from dockertools package, // Need to resolve the code duplication. repoToPull, _, _, err := parsers.ParseImageName(img) if err != nil { return err } keyring, err := credentialprovider.MakeDockerKeyring(pullSecrets, r.dockerKeyring) if err != nil { return err } creds, ok := keyring.Lookup(repoToPull) if !ok { glog.V(1).Infof("Pulling image %s without credentials", img) } userConfigDir, err := ioutil.TempDir("", "rktnetes-user-config-dir-") if err != nil { return fmt.Errorf("rkt: Cannot create a temporary user-config directory: %v", err) } defer os.RemoveAll(userConfigDir) config := *r.config config.UserConfigDir = userConfigDir if err := r.writeDockerAuthConfig(img, creds, userConfigDir); err != nil { return err } if _, err := r.cli.RunCommand(&config, "fetch", dockerPrefix+img); err != nil { glog.Errorf("Failed to fetch: %v", err) return err } return nil }
func (s *SecretCredentialStore) init() credentialprovider.DockerKeyring { s.lock.Lock() defer s.lock.Unlock() if s.keyring != nil { return s.keyring } // lazily load the secrets if s.secrets == nil { if s.secretsFn != nil { s.secrets, s.err = s.secretsFn() } } // TODO: need a version of this that is best effort secret - otherwise one error blocks all secrets keyring, err := credentialprovider.MakeDockerKeyring(s.secrets, emptyKeyring) if err != nil { s.err = err keyring = emptyKeyring } s.keyring = keyring return keyring }
// resolveImageSecret looks up the Secrets provided by the Service Account and // attempt to find a best match for given image. func (g *BuildGenerator) resolveImageSecret(ctx kapi.Context, secrets []kapi.Secret, imageRef *kapi.ObjectReference, buildNamespace string) *kapi.LocalObjectReference { if len(secrets) == 0 || imageRef == nil { return nil } emptyKeyring := credentialprovider.BasicDockerKeyring{} // Get the image pull spec from the image stream reference imageSpec, err := g.resolveImageStreamDockerRepository(ctx, *imageRef, buildNamespace) if err != nil { glog.V(2).Infof("Unable to resolve the image name for %s/%s: %v", buildNamespace, imageRef, err) return nil } for _, secret := range secrets { keyring, err := credentialprovider.MakeDockerKeyring([]kapi.Secret{secret}, &emptyKeyring) if err != nil { glog.V(2).Infof("Unable to make the Docker keyring for %s/%s secret: %v", secret.Name, secret.Namespace, err) continue } if _, found := keyring.Lookup(imageSpec); found { return &kapi.LocalObjectReference{Name: secret.Name} } } glog.V(4).Infof("No secrets found for pushing or pulling the %s %s/%s", imageRef.Kind, buildNamespace, imageRef.Name) return nil }