services/content: move service client into package
Signed-off-by: Stephen J Day <stephen.day@docker.com>
This commit is contained in:
		
							
								
								
									
										76
									
								
								services/content/provider.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								services/content/provider.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | ||||
| package content | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"io" | ||||
|  | ||||
| 	contentapi "github.com/docker/containerd/api/services/content" | ||||
| 	"github.com/docker/containerd/content" | ||||
| 	digest "github.com/opencontainers/go-digest" | ||||
| ) | ||||
|  | ||||
| func NewProviderFromClient(client contentapi.ContentClient) content.Provider { | ||||
| 	return &remoteProvider{ | ||||
| 		client: client, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type remoteProvider struct { | ||||
| 	client contentapi.ContentClient | ||||
| } | ||||
|  | ||||
| func (rp *remoteProvider) Reader(ctx context.Context, dgst digest.Digest) (io.ReadCloser, error) { | ||||
| 	client, err := rp.client.Read(ctx, &contentapi.ReadRequest{Digest: dgst}) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return &remoteReader{ | ||||
| 		client: client, | ||||
| 	}, nil | ||||
| } | ||||
|  | ||||
| type remoteReader struct { | ||||
| 	client contentapi.Content_ReadClient | ||||
| 	extra  []byte | ||||
| } | ||||
|  | ||||
| func (rr *remoteReader) Read(p []byte) (n int, err error) { | ||||
| 	n += copy(p, rr.extra) | ||||
| 	if n >= len(p) { | ||||
| 		if n <= len(rr.extra) { | ||||
| 			rr.extra = rr.extra[n:] | ||||
| 		} else { | ||||
| 			rr.extra = rr.extra[:0] | ||||
| 		} | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	p = p[n:] | ||||
| 	for len(p) > 0 { | ||||
| 		var resp *contentapi.ReadResponse | ||||
| 		// fill our buffer up until we can fill p. | ||||
| 		resp, err = rr.client.Recv() | ||||
| 		if err != nil { | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		copied := copy(p, resp.Data) | ||||
| 		n += copied | ||||
| 		p = p[copied:] | ||||
|  | ||||
| 		if copied < len(p) { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		rr.extra = append(rr.extra, resp.Data[copied:]...) | ||||
| 	} | ||||
|  | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // TODO(stevvooe): Implemente io.ReaderAt. | ||||
|  | ||||
| func (rr *remoteReader) Close() error { | ||||
| 	return rr.client.CloseSend() | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Stephen J Day
					Stephen J Day