Skip to content

Instantly share code, notes, and snippets.

@vbatts
Created April 8, 2014 20:25
Show Gist options
  • Save vbatts/10185925 to your computer and use it in GitHub Desktop.
Save vbatts/10185925 to your computer and use it in GitHub Desktop.
hunting for TarSum inconsistencies

overview

Trying to identify if there is an issue where python's 'tarfile' module lack of support for xattr information along with the checksum.TarSum not including the headers causes an inconsistent tarsum when the image has any xattr information set.

usage

sh repro.sh

FROM fedora:latest
RUN yum install -y attr golang git docker-registry
# this way we'll set something in a non-standard tar pax header for this image
RUN touch file && setfattr -n user.vbatts -v test ./file && getfattr -d ./file
#
RUN curl -kL https://github.com/dotcloud/docker/archive/v0.9.1.tar.gz | tar -zx
RUN mkdir -p /gopath/src/github.com/dotcloud && \
ln -sf /docker-0.9.1 /gopath/src/github.com/dotcloud/docker
ADD . /
RUN GOPATH=/gopath go build /tarsum.go
RUN getfattr -d ./file
RUN setcap 'cap_setgid,cap_setuid+ep' ./file && getcap ./file
CMD /test.sh
$ sh repro.sh
Pulling repository fedora
58394af37342: Download complete
511136ea3c5a: Download complete
8abc22fbb042: Download complete
Uploading context 10.24 kB
Uploading context
Step 0 : FROM fedora:latest
---> 58394af37342
Step 1 : RUN yum install -y attr golang git docker-registry
---> Using cache
---> 6955d48c6cc6
Step 2 : RUN touch file && setfattr -n user.vbatts -v test ./file && getfattr -d ./file
---> Using cache
---> 764322787bc8
Step 3 : RUN curl -kL https://github.com/dotcloud/docker/archive/v0.9.1.tar.gz | tar -zx
---> Using cache
---> 0f62a2ee0285
Step 4 : RUN mkdir -p /gopath/src/github.com/dotcloud && ln -sf /docker-0.9.1 /gopath/src/github.com/dotcloud/docker
---> Using cache
---> 8fcfb470f318
Step 5 : ADD . /
---> 102afbab77a5
Step 6 : RUN GOPATH=/gopath go build /tarsum.go
---> Running in 2db96afb92e4
---> 391a7d7b59c9
Step 7 : CMD /test.sh
---> Running in 5719b1084c7f
---> 9c58e8cf4304
Successfully built 9c58e8cf4304
Removing intermediate container 6942566981c3
Removing intermediate container 2db96afb92e4
Removing intermediate container 5719b1084c7f
working with /tmp/images/58394af373423902a1b97f209a31e3777932d9321ef10e64feaaa7b4df609cf9/json /tmp/images/58394af373423902a1b97f209a31e3777932d9321ef10e64feaaa7b4df609cf9/layer.tar
python github.com/dotcloud/docker-registry lib/checksums.TarSum
tarsum+sha256:adeaa1f621e896c9beba7802073b2f32dbbc73732ae7a13d912cc99805c76eda
golang github.com/dotcloud/docker/utils.TarSum
tarsum+sha256:adeaa1f621e896c9beba7802073b2f32dbbc73732ae7a13d912cc99805c76eda
working with /tmp/images/102afbab77a5bed908f7698c387385017e03c1e2154a408b3d2e6a56de3eb056/json /tmp/images/102afbab77a5bed908f7698c387385017e03c1e2154a408b3d2e6a56de3eb056/layer.tar
python github.com/dotcloud/docker-registry lib/checksums.TarSum
tarsum+sha256:333c80783ac79c648a34d279b66db51c5f25b500534366137943ff297c0693c7
golang github.com/dotcloud/docker/utils.TarSum
tarsum+sha256:333c80783ac79c648a34d279b66db51c5f25b500534366137943ff297c0693c7
working with /tmp/images/6955d48c6cc6aed0fa985590316953e4eeba927528b966fca70a1f7cedc496a3/json /tmp/images/6955d48c6cc6aed0fa985590316953e4eeba927528b966fca70a1f7cedc496a3/layer.tar
python github.com/dotcloud/docker-registry lib/checksums.TarSum
tarsum+sha256:f15df2ab0ec55a8ad84e893ecb4470902bb4549bce9a95faf0e0a610a5219b7d
golang github.com/dotcloud/docker/utils.TarSum
tarsum+sha256:f15df2ab0ec55a8ad84e893ecb4470902bb4549bce9a95faf0e0a610a5219b7d
working with /tmp/images/0f62a2ee0285cad50acacd7370d60d7ffc27ed6f6b8be699355e51b05aa4b504/json /tmp/images/0f62a2ee0285cad50acacd7370d60d7ffc27ed6f6b8be699355e51b05aa4b504/layer.tar
python github.com/dotcloud/docker-registry lib/checksums.TarSum
tarsum+sha256:a4569489ebbf13d28a07dc68934f12aaad0509de40d400a65d33040b4902decb
golang github.com/dotcloud/docker/utils.TarSum
tarsum+sha256:a4569489ebbf13d28a07dc68934f12aaad0509de40d400a65d33040b4902decb
working with /tmp/images/8abc22fbb04266308ff408ca61cb8f6f4244a59308f7efc64e54b08b496c58db/json /tmp/images/8abc22fbb04266308ff408ca61cb8f6f4244a59308f7efc64e54b08b496c58db/layer.tar
python github.com/dotcloud/docker-registry lib/checksums.TarSum
tarsum+sha256:2b8a383a1c7d62d89678a94dfbabbd4c82e201ddf7d3d4f1d160988ab16c44c6
golang github.com/dotcloud/docker/utils.TarSum
tarsum+sha256:2b8a383a1c7d62d89678a94dfbabbd4c82e201ddf7d3d4f1d160988ab16c44c6
working with /tmp/images/391a7d7b59c9e9054efb460c2fdee7e9ebbe60376806dd7e9f3ecc19b6c5c330/json /tmp/images/391a7d7b59c9e9054efb460c2fdee7e9ebbe60376806dd7e9f3ecc19b6c5c330/layer.tar
python github.com/dotcloud/docker-registry lib/checksums.TarSum
tarsum+sha256:a39add6a0329442a7cd8119cedd5e99161be810dd64692fcce55298e5f01c74c
golang github.com/dotcloud/docker/utils.TarSum
tarsum+sha256:a39add6a0329442a7cd8119cedd5e99161be810dd64692fcce55298e5f01c74c
working with /tmp/images/8fcfb470f31866a79ac7f64d3a032654924b04afd2a36ad2b26e1193780c32c5/json /tmp/images/8fcfb470f31866a79ac7f64d3a032654924b04afd2a36ad2b26e1193780c32c5/layer.tar
python github.com/dotcloud/docker-registry lib/checksums.TarSum
tarsum+sha256:43240d4e08c0b76ad7989c7a3c1d7ddee9300a210421f72691054828f772416e
golang github.com/dotcloud/docker/utils.TarSum
tarsum+sha256:43240d4e08c0b76ad7989c7a3c1d7ddee9300a210421f72691054828f772416e
working with /tmp/images/9c58e8cf4304b2a6c0ed3e4ae8ae17a0dc70d9d19fda2c8118e4cdf5b8283c89/json /tmp/images/9c58e8cf4304b2a6c0ed3e4ae8ae17a0dc70d9d19fda2c8118e4cdf5b8283c89/layer.tar
python github.com/dotcloud/docker-registry lib/checksums.TarSum
tarsum+sha256:93fc58bd77e7f103a0eb7c20a84a1ed8781fcbb816dcd8ca3449343d43c89824
golang github.com/dotcloud/docker/utils.TarSum
tarsum+sha256:93fc58bd77e7f103a0eb7c20a84a1ed8781fcbb816dcd8ca3449343d43c89824
working with /tmp/images/511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158/json /tmp/images/511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158/layer.tar
python github.com/dotcloud/docker-registry lib/checksums.TarSum
tarsum+sha256:fc2555cf0a0c89b767bd6849fe4b664d3c48a0585d62362c627f43ac02fde8b6
golang github.com/dotcloud/docker/utils.TarSum
tarsum+sha256:fc2555cf0a0c89b767bd6849fe4b664d3c48a0585d62362c627f43ac02fde8b6
working with /tmp/images/764322787bc81e9f2d4cc785476df453125ba76d6f775eb3dbb2520256e3a51e/json /tmp/images/764322787bc81e9f2d4cc785476df453125ba76d6f775eb3dbb2520256e3a51e/layer.tar
python github.com/dotcloud/docker-registry lib/checksums.TarSum
tarsum+sha256:1c988403eacf52ec59402faed8b13e8f1878bddb8ac0c5b1e1f672fd85f2abf0
golang github.com/dotcloud/docker/utils.TarSum
tarsum+sha256:1c988403eacf52ec59402faed8b13e8f1878bddb8ac0c5b1e1f672fd85f2abf0
NOTICE: remove [/tmp/tmp.rexmKU] when done inspecting
#!/bin/sh
set -e
# this base image is pretty arbitrary
docker pull fedora:latest
d=$(mktemp -d)
# build an image with xattr info set, and tools to get the sum (of itself)
docker build -t test/xattr .
# produce the tar layers of this image with xattr information
docker save test/xattr | tar -C ${d} -x
# run a script in the image, that lets it checksum itself
docker run -i -t --rm -v $d:/tmp/images test/xattr
echo "NOTICE: remove [${d}] when done inspecting"
exit 0
__END__
d=$(mktemp -d)
c=$(docker run -d -v $d:/output debian:latest)
docker pull busybox:latest
docker tag busybox:latest ${b}/busybox
docker push ${b}/busybox
pushd $d
mkdir save
docker save ${b}/busybox | tar -C ./save -x
# docker save leaves these files unreadable
sudo find . \( -type d -exec chmod 0755 "{}" \; \) \( -type f -exec chmod 0644 "{}" \; \)
for path in $(find ./images/ -mindepth 1 -type d) ; do
hash=$(basename ${path})
reg_layer="./images/${hash}/layer"
save_layer="./save/${hash}/layer.tar"
reg_size=$(zcat ${reg_layer} | dd of=/dev/null 2>&1 | grep bytes | cut -d " " -f 1)
save_size=$(cat ${save_layer} | dd of=/dev/null 2>&1 | grep bytes | cut -d " " -f 1)
echo "INFO :: hash: ${hash}; registry size: ${reg_size}; docker save size: ${save_size}"
done
popd $cwd
package main
import (
"io"
"fmt"
"github.com/dotcloud/docker/utils"
"io/ioutil"
"os"
)
func main() {
jsonfile := os.Args[1]
tarfile := os.Args[2]
tar_fh, err := os.Open(tarfile)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
sum, err := SumTarLayer(tar_fh, jsonfile)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Println(sum)
}
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
}
#!/usr/bin/env python
import sys
import tarfile
sys.path.append('/usr/lib/python2.7/site-packages/docker-registry/lib')
import checksums
def main(args):
if len(args) < 3:
print "%s <jsonfile> <tarfile>" % args[0]
return
json_file = args[1]
tar_file = args[2]
jh = open(json_file)
th = open(tar_file)
tarsum = checksums.TarSum(jh.read())
try:
tar = tarfile.open(mode='r|*', fileobj=th)
for member in tar:
tarsum.append(member, tar)
except:
print "Unexpected error:", sys.exc_info()[0]
exit(1)
print tarsum.compute()
main(sys.argv)
#!/bin/sh
# clean up permissions
find /tmp/images/ -type d -exec chmod 0755 "{}" \;
find /tmp/images/ -type f -exec chmod 0644 "{}" \;
for jsonfile in $(find /tmp/images -type f -name 'json'); do
tarfile="$(dirname ${jsonfile})/layer.tar"
echo working with ${jsonfile} ${tarfile}
# this is not a tarsum, but a simple sha256
#python -m docker-registry/lib/checksums ${jsonfile} ${tarfile}
echo python github.com/dotcloud/docker-registry lib/checksums.TarSum
## get TarSum with python
python /tarsum.py ${jsonfile} ${tarfile}
echo golang github.com/dotcloud/docker/utils.TarSum
## get TarSum with golang
/tarsum ${jsonfile} ${tarfile}
echo
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment