func MissingLayers(destHub *registry.Registry, destImage string, srcLayers []manifestV1.FSLayer) []digest.Digest {
	results := make([]digest.Digest, 0)
	var totalSaved int64
	result := make(chan *layerCheckResult)
	for _, layer := range srcLayers {
		go func(layer manifestV1.FSLayer, result chan *layerCheckResult) {
			layerMetada, err := destHub.LayerMetadata(destImage, layer.BlobSum)
			if err != nil {
				checkResult := &layerCheckResult{
					Err: err,
					Missing: &missingLayer{
						Blob: layer.BlobSum,
					},
				}
				result <- checkResult
			} else {
				fmt.Println("Layer already exists on Remote Registry: " + layerMetada.Digest)
				checkResult := &layerCheckResult{
					Err: nil,
					Exists: &existingLayer{
						Descriptor: layerMetada,
					},
				}
				result <- checkResult
			}
		}(layer, result)
	}
	for i := 0; i < len(srcLayers); i++ {
		res := <-result
		if res.Missing != nil {
			var e = false
			for _, r := range results {
				if r == res.Missing.Blob {
					e = true
				}
			}
			if !e {
				results = append(results, res.Missing.Blob)
			}
		} else {
			totalSaved = totalSaved + res.Exists.Descriptor.Size
		}
	}
	fmt.Println()
	if totalSaved > 100 {
		fmt.Printf("Some layers already exist on Remote Registry. Skipping around %s of layer data. Total network bandwidth saved: %s \n", humanize.Bytes(uint64(totalSaved)), humanize.Bytes(uint64(totalSaved*2)))
	}
	fmt.Println()
	return results
}
MissingLayers computes list of layers required to be uploaded. Upload is optimized by skipping existing layers
package layer
import (
	"fmt"
	"os"
	"github.com/docker/distribution"
	"github.com/docker/distribution/digest"
	manifestV1 "github.com/docker/distribution/manifest/schema1"
	humanize "github.com/dustin/go-humanize"
	"github.com/heroku/docker-registry-client/registry"
	"github.com/vbaksa/promoter/progressbar"
)
type layerCheckResult struct {
	Err     error
	Exists  *existingLayer
	Missing *missingLayer
}
type missingLayer struct {
	Blob digest.Digest
}
type existingLayer struct {
	Descriptor distribution.Descriptor
}