Skip to content

Commit

Permalink
Add layer store
Browse files Browse the repository at this point in the history
Layer store manages read-only and read-write layers on a union file system.
Read only layers are always referenced by content addresses.
Read-write layer identifiers are handled by the caller but upon registering
its difference, the committed read-only layer will be referenced by content
hash.

Signed-off-by: Derek McGowan <[email protected]> (github: dmcgowan)
Signed-off-by: Tonis Tiigi <[email protected]>
  • Loading branch information
dmcgowan authored and aaronlehmann committed Nov 24, 2015
1 parent 48c7a16 commit 500e77b
Show file tree
Hide file tree
Showing 13 changed files with 3,278 additions and 0 deletions.
47 changes: 47 additions & 0 deletions layer/empty.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package layer

import (
"archive/tar"
"bytes"
"io"
)

// DigestSHA256EmptyTar is the canonical sha256 digest of empty tar file -
// (1024 NULL bytes)
const DigestSHA256EmptyTar = DiffID("sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef")

type emptyLayer struct{}

// EmptyLayer is a layer that corresponds to empty tar.
var EmptyLayer = &emptyLayer{}

func (el *emptyLayer) TarStream() (io.Reader, error) {
buf := new(bytes.Buffer)
tarWriter := tar.NewWriter(buf)
tarWriter.Close()
return buf, nil
}

func (el *emptyLayer) ChainID() ChainID {
return ChainID(DigestSHA256EmptyTar)
}

func (el *emptyLayer) DiffID() DiffID {
return DigestSHA256EmptyTar
}

func (el *emptyLayer) Parent() Layer {
return nil
}

func (el *emptyLayer) Size() (size int64, err error) {
return 0, nil
}

func (el *emptyLayer) DiffSize() (size int64, err error) {
return 0, nil
}

func (el *emptyLayer) Metadata() (map[string]string, error) {
return make(map[string]string), nil
}
46 changes: 46 additions & 0 deletions layer/empty_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package layer

import (
"io"
"testing"

"github.com/docker/distribution/digest"
)

func TestEmptyLayer(t *testing.T) {
if EmptyLayer.ChainID() != ChainID(DigestSHA256EmptyTar) {
t.Fatal("wrong ID for empty layer")
}

if EmptyLayer.DiffID() != DigestSHA256EmptyTar {
t.Fatal("wrong DiffID for empty layer")
}

if EmptyLayer.Parent() != nil {
t.Fatal("expected no parent for empty layer")
}

if size, err := EmptyLayer.Size(); err != nil || size != 0 {
t.Fatal("expected zero size for empty layer")
}

if diffSize, err := EmptyLayer.DiffSize(); err != nil || diffSize != 0 {
t.Fatal("expected zero diffsize for empty layer")
}

tarStream, err := EmptyLayer.TarStream()
if err != nil {
t.Fatalf("error streaming tar for empty layer: %v", err)
}

digester := digest.Canonical.New()
_, err = io.Copy(digester.Hash(), tarStream)

if err != nil {
t.Fatalf("error hashing empty tar layer: %v", err)
}

if digester.Digest() != digest.Digest(DigestSHA256EmptyTar) {
t.Fatal("empty layer tar stream hashes to wrong value")
}
}
Loading

0 comments on commit 500e77b

Please sign in to comment.