...

Text file src/github.com/google/go-containerregistry/pkg/v1/stream/README.md

Documentation: github.com/google/go-containerregistry/pkg/v1/stream

     1# `stream`
     2
     3[![GoDoc](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/stream?status.svg)](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/stream)
     4
     5The `stream` package contains an implementation of
     6[`v1.Layer`](https://godoc.org/github.com/google/go-containerregistry/pkg/v1#Layer)
     7that supports _streaming_ access, i.e. the layer contents are read once and not
     8buffered.
     9
    10## Usage
    11
    12```go
    13package main
    14
    15import (
    16	"os"
    17
    18	"github.com/google/go-containerregistry/pkg/name"
    19	"github.com/google/go-containerregistry/pkg/v1/remote"
    20	"github.com/google/go-containerregistry/pkg/v1/stream"
    21)
    22
    23// upload the contents of stdin as a layer to a local registry
    24func main() {
    25	repo, err := name.NewRepository("localhost:5000/stream")
    26	if err != nil {
    27		panic(err)
    28	}
    29
    30	layer := stream.NewLayer(os.Stdin)
    31
    32	if err := remote.WriteLayer(repo, layer); err != nil {
    33		panic(err)
    34	}
    35}
    36```
    37
    38## Structure
    39
    40This implements the layer portion of an [image
    41upload](/pkg/v1/remote#anatomy-of-an-image-upload). We launch a goroutine that
    42is responsible for hashing the uncompressed contents to compute the `DiffID`,
    43gzipping them to produce the `Compressed` contents, and hashing/counting the
    44bytes to produce the `Digest`/`Size`. This goroutine writes to an
    45`io.PipeWriter`, which blocks until `Compressed` reads the gzipped contents from
    46the corresponding `io.PipeReader`.
    47
    48<p align="center">
    49  <img src="/images/stream.dot.svg" />
    50</p>
    51
    52## Caveats
    53
    54This assumes that you have an uncompressed layer (i.e. a tarball) and would like
    55to compress it. Calling `Uncompressed` is always an error. Likewise, other
    56methods are invalid until the contents of `Compressed` have been completely
    57consumed and `Close`d.
    58
    59Using a `stream.Layer` will likely not work without careful consideration. For
    60example, in the `mutate` package, we defer computing the manifest and config
    61file until they are actually called. This allows you to `mutate.Append` a
    62streaming layer to an image without accidentally consuming it. Similarly, in
    63`remote.Write`, if calling `Digest` on a layer fails, we attempt to upload the
    64layer anyway, understanding that we may be dealing with a `stream.Layer` whose
    65contents need to be uploaded before we can upload the config file.
    66
    67Given the [structure](#structure) of how this is implemented, forgetting to
    68`Close` a `stream.Layer` will leak a goroutine.

View as plain text