diff --git a/main.go b/main.go index 700f2b6..7b2b34c 100644 --- a/main.go +++ b/main.go @@ -15,7 +15,6 @@ type ( } cmdManifest struct{} // stub - ) func main() { diff --git a/rootfs/BUILD b/rootfs/BUILD index ca38d4e..eaef33a 100644 --- a/rootfs/BUILD +++ b/rootfs/BUILD @@ -2,7 +2,10 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") go_library( name = "rootfs_lib", - srcs = ["rootfs.go"], + srcs = [ + "rootfs.go", + "rootfs_tests.go", + ], importpath = "github.com/motiejus/code/undocker/rootfs", visibility = ["//visibility:public"], ) diff --git a/rootfs/rootfs.go b/rootfs/rootfs.go index 4c3f1e8..bf99fce 100644 --- a/rootfs/rootfs.go +++ b/rootfs/rootfs.go @@ -26,7 +26,7 @@ type dockerManifestJSON []struct { // I) layer name // II) offset (0 being the first file in the layer) // 4. go through -func Rootfs(in io.ReadSeeker, out io.Writer) error { +func RootFS(in io.ReadSeeker, out io.Writer) error { tr := tar.NewReader(in) tw := tar.NewWriter(out) // layerOffsets maps a layer name (a9b123c0daa/layer.tar) to it's offset diff --git a/rootfs/rootfs_tests.go b/rootfs/rootfs_tests.go new file mode 100644 index 0000000..a858792 --- /dev/null +++ b/rootfs/rootfs_tests.go @@ -0,0 +1,82 @@ +package rootfs + +import ( + "archive/tar" + "bytes" + "encoding/json" + "testing" +) + +type layers []string + +func (l layers) bytes() []byte { + dockerManifest := dockerManifestJSON{{Layers: l}} + b, err := json.Marshal(dockerManifest) + if err != nil { + panic("panic in a unit test") + } + return b +} + +type tarrable interface { + tar(*tar.Writer) +} + +type file struct { + name string + contents []byte + uid int +} + +func (f file) tar(tw *tar.Writer) { + hdr := &tar.Header{Typeflag: tar.TypeReg, Uid: f.uid} + tw.WriteHeader(hdr) + tw.Write(f.contents) +} + +type dir struct { + name string + uid int +} + +func (f dir) tar(tw *tar.Writer) { + hdr := &tar.Header{Typeflag: tar.TypeDir, Uid: f.uid} + tw.WriteHeader(hdr) +} + +type tarball []tarrable + +func (t tarball) bytes() []byte { + buf := bytes.Buffer{} + tw := tar.NewWriter(&buf) + for _, member := range t { + member.tar(tw) + } + tw.Close() + return buf.Bytes() +} + +var ( + _layer0 = tarball{ + dir{name: "/", uid: 0}, + file{name: "/file", uid: 1, contents: []byte("from 0")}, + } + + _layer1 = tarball{ + dir{name: "/", uid: 1}, + file{name: "/file", uid: 0, contents: []byte("from 1")}, + } + + _image = tarball{ + file{name: "layer1/layer.tar", contents: _layer1.bytes()}, + file{name: "layer0/layer.tar", contents: _layer0.bytes()}, + file{ + name: "manifest.json", + contents: layers{"layer0/layer.tar", "layer1/layer0.tar"}.bytes(), + }, + } +) + +func RootFSTest(t *testing.T) { + +}