func (e dirLayout) PutBlob(ctx context.Context, reader io.Reader) (string, int64, error) {
	hash := sha256.New()
	algo := BlobAlgorithm
	fh, err := ioutil.TempFile(e.temp, "blob-")
	if err != nil {
		return "", -1, err
	}
	tempPath := fh.Name()
	defer fh.Close()
	writer := io.MultiWriter(fh, hash)
	size, err := io.Copy(writer, reader)
	if err != nil {
		return "", -1, err
	}
	fh.Close()
	digest := fmt.Sprintf("%s:%x", algo, hash.Sum(nil))
	path, err := blobPath(digest)
	if err != nil {
		return "", -1, err
	}
	path = filepath.Join(e.path, path)
	if err := os.Rename(tempPath, path); err != nil {
		return "", -1, err
	}
	return digest, int64(size), nil
}
PutBlob adds a new blob to the image. This is idempotent; a nil error
means that "the content is stored at DIGEST" without implying "because
of this PutBlob() call".
package oci
import (
	"crypto/sha256"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"reflect"
	"github.com/opencontainers/image-spec/specs-go/v1"
	"golang.org/x/net/context"
)
type ImageLayout struct {
	Version string `json:"imageLayoutVersion"`
}
const ImageLayoutVersion = "1.0.0"
type dirLayout struct {
	path string
	temp string
}
func (e dirLayout) initialize() error {
	path := e.path
	dir := filepath.Dir(path)
	if dir != "." {
		if err := os.MkdirAll(dir, 0755); err != nil && !os.IsExist(err) {
			return err
		}
	}
	if err := os.Mkdir(path, 0755); err != nil && !os.IsExist(err) {
		return err
	}
	if _, err := os.Stat(filepath.Join(path, layoutFile)); err == nil {
		return nil
	}
	if err := os.Mkdir(filepath.Join(path, blobDirectory), 0755); err != nil {
		return err
	}
	if err := os.Mkdir(filepath.Join(path, blobDirectory, BlobAlgorithm), 0755); err != nil {
		return err
	}
	if err := os.Mkdir(filepath.Join(path, refDirectory), 0755); err != nil {
		return err
	}
	fh, err := os.Create(filepath.Join(path, layoutFile))
	if err != nil {
		return err
	}
	defer fh.Close()
	ociLayout := &ImageLayout{
		Version: ImageLayoutVersion,
	}
	if err := json.NewEncoder(fh).Encode(ociLayout); err != nil {
		return err
	}
	return nil
}