func (daemon *Daemon) pullImageWithReference(ctx context.Context, ref reference.Named, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error { // Include a buffer so that slow client connections don't affect // transfer performance. progressChan := make(chan progress.Progress, 100) writesDone := make(chan struct{}) ctx, cancelFunc := context.WithCancel(ctx) go func() { progressutils.WriteDistributionProgress(cancelFunc, outStream, progressChan) close(writesDone) }() imagePullConfig := &distribution.ImagePullConfig{ Config: distribution.Config{ MetaHeaders: metaHeaders, AuthConfig: authConfig, ProgressOutput: progress.ChanOutput(progressChan), RegistryService: daemon.RegistryService, ImageEventLogger: daemon.LogImageEvent, MetadataStore: daemon.distributionMetadataStore, ImageStore: distribution.NewImageConfigStoreFromStore(daemon.imageStore), ReferenceStore: daemon.referenceStore, }, DownloadManager: daemon.downloadManager, Schema2Types: distribution.ImageTypes, } err := distribution.Pull(ctx, ref, imagePullConfig) close(progressChan) <-writesDone return err }
func (pm *Manager) pull(ctx context.Context, ref reference.Named, config *distribution.ImagePullConfig, outStream io.Writer) error { if outStream != nil { // Include a buffer so that slow client connections don't affect // transfer performance. progressChan := make(chan progress.Progress, 100) writesDone := make(chan struct{}) defer func() { close(progressChan) <-writesDone }() var cancelFunc context.CancelFunc ctx, cancelFunc = context.WithCancel(ctx) go func() { progressutils.WriteDistributionProgress(cancelFunc, outStream, progressChan) close(writesDone) }() config.ProgressOutput = progress.ChanOutput(progressChan) } else { config.ProgressOutput = progress.DiscardOutput() } return distribution.Pull(ctx, ref, config) }
// PushImage initiates a push operation on the repository named localName. func (daemon *Daemon) PushImage(ctx context.Context, image, tag string, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error { ref, err := reference.ParseNamed(image) if err != nil { return err } if tag != "" { // Push by digest is not supported, so only tags are supported. ref, err = reference.WithTag(ref, tag) if err != nil { return err } } // Include a buffer so that slow client connections don't affect // transfer performance. progressChan := make(chan progress.Progress, 100) writesDone := make(chan struct{}) ctx, cancelFunc := context.WithCancel(ctx) go func() { progressutils.WriteDistributionProgress(cancelFunc, outStream, progressChan) close(writesDone) }() imagePushConfig := &distribution.ImagePushConfig{ Config: distribution.Config{ MetaHeaders: metaHeaders, AuthConfig: authConfig, ProgressOutput: progress.ChanOutput(progressChan), RegistryService: daemon.RegistryService, ImageEventLogger: daemon.LogImageEvent, MetadataStore: daemon.distributionMetadataStore, ImageStore: distribution.NewImageConfigStoreFromStore(daemon.imageStore), ReferenceStore: daemon.referenceStore, }, ConfigMediaType: schema2.MediaTypeImageConfig, LayerStore: distribution.NewLayerProviderFromStore(daemon.layerStore), TrustKey: daemon.trustKey, UploadManager: daemon.uploadManager, } err = distribution.Push(ctx, ref, imagePushConfig) close(progressChan) <-writesDone return err }
// Push pushes a plugin to the store. func (pm *Manager) Push(ctx context.Context, name string, metaHeader http.Header, authConfig *types.AuthConfig, outStream io.Writer) error { p, err := pm.config.Store.GetV2Plugin(name) if err != nil { return err } ref, err := reference.ParseNamed(p.Name()) if err != nil { return errors.Wrapf(err, "plugin has invalid name %v for push", p.Name()) } var po progress.Output if outStream != nil { // Include a buffer so that slow client connections don't affect // transfer performance. progressChan := make(chan progress.Progress, 100) writesDone := make(chan struct{}) defer func() { close(progressChan) <-writesDone }() var cancelFunc context.CancelFunc ctx, cancelFunc = context.WithCancel(ctx) go func() { progressutils.WriteDistributionProgress(cancelFunc, outStream, progressChan) close(writesDone) }() po = progress.ChanOutput(progressChan) } else { po = progress.DiscardOutput() } // TODO: replace these with manager is := &pluginConfigStore{ pm: pm, plugin: p, } ls := &pluginLayerProvider{ pm: pm, plugin: p, } rs := &pluginReference{ name: ref, pluginID: p.Config, } uploadManager := xfer.NewLayerUploadManager(3) imagePushConfig := &distribution.ImagePushConfig{ Config: distribution.Config{ MetaHeaders: metaHeader, AuthConfig: authConfig, ProgressOutput: po, RegistryService: pm.config.RegistryService, ReferenceStore: rs, ImageEventLogger: pm.config.LogPluginEvent, ImageStore: is, RequireSchema2: true, }, ConfigMediaType: schema2.MediaTypePluginConfig, LayerStore: ls, UploadManager: uploadManager, } return distribution.Push(ctx, ref, imagePushConfig) }