Skip to content

Instantly share code, notes, and snippets.

@vbatts
Last active August 29, 2015 13:57
Show Gist options
  • Save vbatts/9537339 to your computer and use it in GitHub Desktop.
Save vbatts/9537339 to your computer and use it in GitHub Desktop.
docker image/layer sums
package main
import (
"compress/gzip"
"flag"
"fmt"
"github.com/dotcloud/docker/image"
"github.com/dotcloud/docker/utils"
"io"
"io/ioutil"
"os"
"path/filepath"
"strings"
)
var (
flRegistry = flag.Bool("registry", false, "assume the walked tree is a docker-registry")
)
func main() {
flag.Parse()
if flag.NArg() == 0 {
fmt.Fprintln(os.Stderr, "please provide path(s) to walk")
os.Exit(1)
}
for _, arg := range flag.Args() {
err := filepath.Walk(arg, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if *flRegistry && strings.Contains(path, "images") && info.Mode().IsRegular() && filepath.Base(path) == "layer" {
// validate tarsum of layers in a registry
json, err := filepath.Abs(filepath.Join(filepath.Dir(path), "json"))
if err != nil {
return err
}
fmt.Println(path)
sum, err := SumLayer(path, json)
if err != nil {
return err
}
fmt.Println(sum)
checksum, err := filepath.Abs(filepath.Join(filepath.Dir(path), "_checksum"))
if err != nil {
return err
}
buf, err := func() ([]byte, error) {
ch_fh, err := os.Open(checksum)
if err != nil {
return []byte{}, err
}
defer ch_fh.Close()
return ioutil.ReadAll(ch_fh)
}()
if err != nil {
return err
}
if sum == string(buf) {
fmt.Printf("SUCCESS: %s matches\n", sum)
} else {
fmt.Printf("FAILED: %s does not match %s\n", sum, string(buf))
}
} else if strings.Contains(path, "graph/") && info.Mode().IsRegular() && filepath.Base(path) == "json" {
// calculate tarsum of layers on a local docker instance
buf, err := func() ([]byte, error) {
ch_fh, err := os.Open(path)
if err != nil {
return []byte{}, err
}
defer ch_fh.Close()
return ioutil.ReadAll(ch_fh)
}()
if err != nil {
return err
}
img, err := image.NewImgJSON(buf)
if err != nil {
return err
}
fmt.Printf("%s\n", img.ID)
//fmt.Printf("%#v\n", img)
tarLayer, err := img.TarLayer()
if err != nil {
return err
}
defer tarLayer.Close()
sum, err := SumTarLayer(tarLayer, path)
if err != nil {
return err
}
fmt.Println(sum)
}
return nil
})
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
}
}
func SumTarLayer(tar io.ReadCloser, json string) (string, error) {
json_fh, err := os.Open(json)
if err != nil {
return "", err
}
defer json_fh.Close()
ts := &utils.TarSum{Reader: tar}
_, err = io.Copy(ioutil.Discard, ts)
if err != nil {
return "", err
}
buf, err := ioutil.ReadAll(json_fh)
if err != nil {
return "", err
}
return ts.Sum(buf), nil
}
func SumLayer(layer, json string) (string, error) {
fh, err := os.Open(layer)
if err != nil {
return "", err
}
defer fh.Close()
json_fh, err := os.Open(json)
if err != nil {
return "", err
}
defer json_fh.Close()
gz_rdr, err := gzip.NewReader(fh)
if err != nil {
return "", err
}
ts := &utils.TarSum{Reader: gz_rdr}
_, err = io.Copy(ioutil.Discard, ts)
if err != nil {
return "", err
}
buf, err := ioutil.ReadAll(json_fh)
if err != nil {
return "", err
}
return ts.Sum(buf), nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment