#!/usr/bin/env bats load helpers @test "idmaps-create-apply-layer" { # This test needs "tar". if test -z "$(which tar 2> /dev/null)" ; then skip "need tar" fi if [ "$OS" != "Linux" ]; then skip "not supported on $OS" fi case "$STORAGE_DRIVER" in btrfs|overlay*|vfs|zfs) ;; *) skip "not supported by driver $STORAGE_DRIVER" ;; esac case "$STORAGE_OPTION" in *mount_program*) skip "test not supported when using mount_program" ;; esac n=5 host=2 # Create some temporary files. for i in $(seq $n) ; do createrandom "$TESTDIR"/file$i chown ${i}:${i} "$TESTDIR"/file$i ln -s . $TESTDIR/subdir$i done # Use them to create some diffs. pushd $TESTDIR > /dev/null for i in $(seq $n) ; do tar cf diff${i}.tar subdir$i/ done popd > /dev/null # Select some ID ranges. for i in $(seq $n) ; do uidrange[$i]=$((($RANDOM+32767)*65536)) gidrange[$i]=$((($RANDOM+32767)*65536)) done # Create a layer using the host's mappings. run storage --debug=false create-layer --hostuidmap --hostgidmap echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] lowerlayer="$output" # Mount the layer. run storage --debug=false mount $lowerlayer echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] lowermount="$output" # Copy the files in (host mapping, so it's fine), and set ownerships on them. cp -p "$TESTDIR"/file1 ${lowermount} cp -p "$TESTDIR"/file2 ${lowermount} cp -p "$TESTDIR"/file3 ${lowermount} cp -p "$TESTDIR"/file4 ${lowermount} cp -p "$TESTDIR"/file5 ${lowermount} # Create a hard link createrandom ${lowermount}/origin-file ln ${lowermount}/origin-file ${lowermount}/ln-file # Create new layers. for i in $(seq $n) ; do if test $host -ne $i ; then run storage --debug=false create-layer --uidmap 0:${uidrange[$i]}:$(($n+1)) --gidmap 0:${gidrange[$i]}:$(($n+1)) $lowerlayer else uidrange[$host]=0 gidrange[$host]=0 run storage --debug=false create-layer --hostuidmap --hostgidmap $lowerlayer fi echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] upperlayer="$output" run storage --debug=false mount $upperlayer echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] uppermount="$output" run storage --debug=false apply-diff $upperlayer < ${TESTDIR}/diff${i}.tar echo "$output" [ "$status" -eq 0 ] [ "$output" = "" ] # Verify that the hard link is maintained origin_ino=$(stat -c %i ${uppermount}/origin-file) ln_ino=$(stat -c %i ${uppermount}/ln-file) echo test ${origin_ino} = ${ln_ino} test ${origin_ino} = ${ln_ino} for j in $(seq $n) ; do # Check the inherited original files. cmp ${uppermount}/file$j "$TESTDIR"/file$j uid=$(stat -c %u ${uppermount}/file$j) gid=$(stat -c %g ${uppermount}/file$j) echo test found ${uid}:${gid} = expected $((${uidrange[$i]}+$j)):$((${gidrange[$i]}+$j)) for file$j test ${uid}:${gid} = $((${uidrange[$i]}+$j)):$((${gidrange[$i]}+$j)) # Check the inherited/current layer's diff files. for k in $(seq $i) ; do cmp ${uppermount}/subdir$k/file$j "$TESTDIR"/file$j uid=$(stat -c %u ${uppermount}/subdir$k/file$j) gid=$(stat -c %g ${uppermount}/subdir$k/file$j) echo test found ${uid}:${gid} = expected $((${uidrange[$i]}+$j)):$((${gidrange[$i]}+$j)) for subdir$k/file$j test ${uid}:${gid} = $((${uidrange[$i]}+$j)):$((${gidrange[$i]}+$j)) done done lowerlayer=$upperlayer done } @test "idmaps-create-diff-layer" { # This test needs "tar". if test -z "$(which tar 2> /dev/null)" ; then skip "need tar" fi if [ "$OS" != "Linux" ]; then skip "not supported on $OS" fi case "$STORAGE_DRIVER" in btrfs|overlay*|vfs|zfs) ;; *) skip "not supported by driver $STORAGE_DRIVER" ;; esac case "$STORAGE_OPTION" in *mount_program*) skip "test not supported when using mount_program" ;; esac n=5 host=2 # Create some temporary files. for i in $(seq $n) ; do createrandom "$TESTDIR"/file$i done # Select some ID ranges. for i in 0 $(seq $n) ; do uidrange[$i]=$((($RANDOM+32767)*65536)) gidrange[$i]=$((($RANDOM+32767)*65536)) done # Create a layer using some random mappings. run storage --debug=false create-layer --uidmap 0:${uidrange[0]}:$(($n+1)) --gidmap 0:${gidrange[0]}:$(($n+1)) echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] lowerlayer="$output" # Mount the layer. run storage --debug=false mount $lowerlayer echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] lowermount="$output" # Copy the files in, and set ownerships on them. for i in $(seq $n) ; do cp "$TESTDIR"/file$i ${lowermount} chown $((${uidrange[0]}+$i)):$((${gidrange[0]}+$i)) ${lowermount}/file$i done # Create new layers. for i in $(seq $n) ; do if test $host -ne $i ; then run storage --debug=false create-layer --uidmap 0:${uidrange[$i]}:$(($n+1)) --gidmap 0:${gidrange[$i]}:$(($n+1)) $lowerlayer else uidrange[$host]=0 gidrange[$host]=0 run storage --debug=false create-layer --hostuidmap --hostgidmap $lowerlayer fi echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] upperlayer="$output" run storage --debug=false mount $upperlayer echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] uppermount="$output" # Change the owner of one file to 0:0. chown ${uidrange[$i]}:${gidrange[$i]} ${uppermount}/file$i # Verify that the file is the only thing that shows up in a change list. run storage --debug=false changes $upperlayer echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] [ "${#lines[*]}" -eq 1 ] [ "$output" = "Modify \"/file$i\"" ] # Verify that the file is the only thing that shows up in a diff. run storage --debug=false diff -f $TESTDIR/diff.tar $upperlayer echo "$output" [ "$status" -eq 0 ] run tar tf $TESTDIR/diff.tar echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] [ "${#lines[*]}" -eq 1 ] [ "$output" = file$i ] # Check who owns that file, according to the diff. mkdir "$TESTDIR"/subdir$i pushd "$TESTDIR"/subdir$i > /dev/null run tar xf $TESTDIR/diff.tar [ "$status" -eq 0 ] run stat -c %u:%g file$i [ "$status" -eq 0 ] [ "$output" = 0:0 ] popd > /dev/null lowerlayer=$upperlayer done } @test "idmaps-create-container" { if [ "$OS" != "Linux" ]; then skip "not supported on $OS" fi case "$STORAGE_DRIVER" in btrfs|overlay*|vfs|zfs) ;; *) skip "not supported by driver $STORAGE_DRIVER" ;; esac case "$STORAGE_OPTION" in *mount_program*) skip "test not supported when using mount_program" ;; esac n=5 host=2 # Create some temporary files. for i in $(seq $n) ; do createrandom "$TESTDIR"/file$i done # Select some ID ranges. for i in 0 $(seq $(($n+1))) ; do uidrange[$i]=$((($RANDOM+32767)*65536)) gidrange[$i]=$((($RANDOM+32767)*65536)) done # Create a layer using some random mappings. run storage --debug=false create-layer --uidmap 0:${uidrange[0]}:$(($n+1)) --gidmap 0:${gidrange[0]}:$(($n+1)) echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] lowerlayer="$output" # Mount the layer. run storage --debug=false mount $lowerlayer echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] lowermount="$output" # Copy the files in, and set ownerships on them. for i in $(seq $n) ; do cp "$TESTDIR"/file$i ${lowermount} chown $((${uidrange[0]}+$i)):$((${gidrange[0]}+$i)) ${lowermount}/file$i done # Create new layers. for i in $(seq $n) ; do if test $host -ne $i ; then run storage --debug=false create-layer --uidmap 0:${uidrange[$i]}:$(($n+1)) --gidmap 0:${gidrange[$i]}:$(($n+1)) $lowerlayer else uidrange[$host]=0 gidrange[$host]=0 run storage --debug=false create-layer --hostuidmap --hostgidmap $lowerlayer fi echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] upperlayer="$output" run storage --debug=false mount $upperlayer echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] uppermount="$output" # Change the owner of one file to 0:0. chown ${uidrange[$i]}:${gidrange[$i]} ${uppermount}/file$i # Verify that the file is the only thing that shows up in a change list. run storage --debug=false changes $upperlayer echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] [ "${#lines[*]}" -eq 1 ] [ "$output" = "Modify \"/file$i\"" ] lowerlayer=$upperlayer done # Create new containers based on the layer. imagename=idmappedimage storage create-image --name=$imagename $lowerlayer run storage --debug=false create-container --hostuidmap --hostgidmap $imagename [ "$status" -eq 0 ] [ "$output" != "" ] hostcontainer="$output" run storage --debug=false mount $hostcontainer [ "$status" -eq 0 ] [ "$output" != "" ] hostmount="$output" for i in $(seq $n) ; do run stat -c %u:%g "$hostmount"/file$i [ "$status" -eq 0 ] [ "$output" = 0:0 ] done run storage --debug=false create-container --hostuidmap --hostgidmap $imagename [ "$status" -eq 0 ] [ "$output" != "" ] hostcontainer="$output" run storage --debug=false mount $hostcontainer [ "$status" -eq 0 ] [ "$output" != "" ] hostmount="$output" for i in $(seq $n) ; do run stat -c %u:%g "$hostmount"/file$i [ "$status" -eq 0 ] [ "$output" = 0:0 ] done run storage --debug=false create-container --uidmap 0:${uidrange[$(($n+1))]}:$(($n+1)) --gidmap 0:${gidrange[$(($n+1))]}:$(($n+1)) $imagename [ "$status" -eq 0 ] [ "$output" != "" ] newmapcontainer="$output" run storage --debug=false mount $newmapcontainer [ "$status" -eq 0 ] [ "$output" != "" ] newmapmount="$output" for i in $(seq $n) ; do run stat -c %u:%g "$newmapmount"/file$i [ "$status" -eq 0 ] [ "$output" = ${uidrange[$(($n+1))]}:${gidrange[$(($n+1))]} ] done run storage --debug=false create-container $imagename [ "$status" -eq 0 ] [ "$output" != "" ] defmapcontainer="$output" run storage --debug=false mount $defmapcontainer [ "$status" -eq 0 ] [ "$output" != "" ] defmapmount="$output" for i in $(seq $n) ; do run stat -c %u:%g "$defmapmount"/file$i [ "$status" -eq 0 ] [ "$output" = "0:0" ] done } @test "idmaps-parent-owners" { if [ "$OS" != "Linux" ]; then skip "not supported on $OS" fi case "$STORAGE_DRIVER" in btrfs|overlay*|vfs|zfs) ;; *) skip "not supported by driver $STORAGE_DRIVER" ;; esac case "$STORAGE_OPTION" in *mount_program*) skip "test not supported when using mount_program" ;; esac n=5 # Create some temporary files. for i in $(seq $n) ; do createrandom "$TESTDIR"/file$i done # Select some ID ranges. uidrange=$((($RANDOM+32767)*65536)) gidrange=$((($RANDOM+32767)*65536)) # Create a layer using some random mappings. run storage --debug=false create-layer --uidmap 0:${uidrange}:$(($n+1)) --gidmap 0:${gidrange}:$(($n+1)) echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] layer="$output" # Mount the layer. run storage mount $layer echo "$output" [ "$status" -eq 0 ] # Check who owns the parent directories. run storage --debug=false layer-parent-owners $layer echo "$output" [ "$status" -eq 0 ] # Assume that except for root and maybe us, there are no other owners of parent directories of our layer. if ! fgrep -q 'UIDs: [0]' <<< "$output" ; then fgrep -q 'UIDs: [0, '$(id -u)']' <<< "$output" fi if ! fgrep -q 'GIDs: [0]' <<< "$output" ; then fgrep -q 'GIDs: [0, '$(id -g)']' <<< "$output" fi # Create a new container based on the layer. imagename=idmappedimage storage create-image --name=$imagename $layer run storage --debug=false create-container $imagename [ "$status" -eq 0 ] [ "$output" != "" ] container="$output" # Mount the container. run storage mount $container echo "$output" [ "$status" -eq 0 ] # Check who owns the parent directories. run storage --debug=false container-parent-owners $container [ "$status" -eq 0 ] cat <<< "$output" | tr '\n' '_' # Check there are no unmapped IDs fgrep -q 'UIDs: []' <<< "$output" fgrep -q 'GIDs: []' <<< "$output" } @test "idmaps-copy" { if [ "$OS" != "Linux" ]; then skip "not supported on $OS" fi case "$STORAGE_DRIVER" in btrfs|overlay*|vfs|zfs) ;; *) skip "not supported by driver $STORAGE_DRIVER" ;; esac case "$STORAGE_OPTION" in *mount_program*) skip "test not supported when using mount_program" ;; esac n=5 host=2 # Create some temporary files. mkdir -p "$TESTDIR"/subdir/subdir2 for i in 0 $(seq $n) ; do createrandom "$TESTDIR"/file$i chown "$i":"$i" "$TESTDIR"/file$i createrandom "$TESTDIR"/subdir/subdir2/file$i chown "$i":"$i" "$TESTDIR"/subdir/subdir2/file$i done chown "$(($n+1))":"$(($n+1))" "$TESTDIR"/subdir/subdir2 # Select some ID ranges for ID mappings. for i in 0 $(seq $(($n+1))) ; do uidrange[$i]=$((($RANDOM+32767)*65536)) gidrange[$i]=$((($RANDOM+32767)*65536)) # Create a layer using some those mappings. run storage --debug=false create-layer --uidmap 0:${uidrange[$i]}:101 --gidmap 0:${gidrange[$i]}:101 echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] layer[$i]="$output" done # Copy the file in, and check that its ownerships get mapped correctly. for i in 0 $(seq $n) ; do run storage copy "$TESTDIR"/file$i ${layer[$i]}:/file$i echo "$output" [ "$status" -eq 0 ] run storage --debug=false mount ${layer[$i]} echo "$output" [ "$status" -eq 0 ] mnt[$i]="$output" run stat -c "%u:%g" ${mnt[$i]}/file$i echo "$output" [ "$status" -eq 0 ] uid=$((${uidrange[$i]}+$i)) gid=$((${gidrange[$i]}+$i)) echo comparing "$output" and "$uid:$gid" [ "$output" == "$uid:$gid" ] # Try copying with --chown. run storage copy --chown 100:100 "$TESTDIR"/file$i ${layer[$i]}:/file$i echo "$output" [ "$status" -eq 0 ] run storage --debug=false mount ${layer[$i]} echo "$output" [ "$status" -eq 0 ] mnt[$i]="$output" run stat -c "%u:%g" ${mnt[$i]}/file$i echo "$output" [ "$status" -eq 0 ] uid=$((${uidrange[$i]}+100)) gid=$((${gidrange[$i]}+100)) echo comparing "$output" and "$uid:$gid" [ "$output" == "$uid:$gid" ] done # Copy the subdirectory, and check that its ownerships and that of its contents get mapped correctly. for i in 0 $(seq $n) ; do run storage copy "$TESTDIR"/file$i ${layer[$i]}:/file$i echo "$output" [ "$status" -eq 0 ] run stat -c "%u:%g" ${mnt[$i]}/file$i echo "$output" [ "$status" -eq 0 ] uid=$((${uidrange[$i]}+$i)) gid=$((${gidrange[$i]}+$i)) echo comparing "$output" and "$uid:$gid" [ "$output" == "$uid:$gid" ] # Try copying with --chown. run storage copy --chown 100:100 "$TESTDIR"/file$i ${layer[$i]}:/file$i echo "$output" [ "$status" -eq 0 ] run stat -c "%u:%g" ${mnt[$i]}/file$i echo "$output" [ "$status" -eq 0 ] uid=$((${uidrange[$i]}+100)) gid=$((${gidrange[$i]}+100)) echo comparing "$output" and "$uid:$gid" [ "$output" == "$uid:$gid" ] # Try copying a directory tree. run storage copy "$TESTDIR"/subdir ${layer[$i]}:/subdir echo "$output" [ "$status" -eq 0 ] run stat -c "%u:%g" ${mnt[$i]}/subdir/subdir2/file$i echo "$output" [ "$status" -eq 0 ] uid=$((${uidrange[$i]}+$i)) gid=$((${gidrange[$i]}+$i)) echo comparing "$output" and "$uid:$gid" [ "$output" == "$uid:$gid" ] run stat -c "%u:%g" ${mnt[$i]}/subdir/subdir2 echo "$output" [ "$status" -eq 0 ] uid=$((${uidrange[$i]}+$n+1)) gid=$((${gidrange[$i]}+$n+1)) echo comparing "$output" and "$uid:$gid" [ "$output" == "$uid:$gid" ] # Try copying a directory tree with --chown. run storage copy --chown 100:100 "$TESTDIR"/subdir ${layer[$i]}:/subdir2 echo "$output" [ "$status" -eq 0 ] run stat -c "%u:%g" ${mnt[$i]}/subdir2/subdir2/file$i echo "$output" [ "$status" -eq 0 ] uid=$((${uidrange[$i]}+100)) gid=$((${gidrange[$i]}+100)) echo comparing "$output" and "$uid:$gid" [ "$output" == "$uid:$gid" ] run stat -c "%u:%g" ${mnt[$i]}/subdir2/subdir2 echo "$output" [ "$status" -eq 0 ] uid=$((${uidrange[$i]}+100)) gid=$((${gidrange[$i]}+100)) echo comparing "$output" and "$uid:$gid" [ "$output" == "$uid:$gid" ] done # Copy a file out of a layer, into another one. run storage copy "$TESTDIR"/file$n ${layer[0]}:/file$n echo "$output" [ "$status" -eq 0 ] run storage copy ${layer[0]}:/file$n ${layer[$n]}:/file$n echo "$output" [ "$status" -eq 0 ] run stat -c "%u:%g" ${mnt[$n]}/file$n echo "$output" [ "$status" -eq 0 ] uid=$((${uidrange[$n]}+$n)) gid=$((${gidrange[$n]}+$n)) echo comparing "$output" and "$uid:$gid" [ "$output" == "$uid:$gid" ] # Try copying a directory tree. run storage copy ${layer[0]}:/subdir ${layer[$n]}:/subdir echo "$output" [ "$status" -eq 0 ] run stat -c "%u:%g" ${mnt[$n]}/subdir/subdir2/file$n echo "$output" [ "$status" -eq 0 ] uid=$((${uidrange[$n]}+$n)) gid=$((${gidrange[$n]}+$n)) echo comparing "$output" and "$uid:$gid" [ "$output" == "$uid:$gid" ] run stat -c "%u:%g" ${mnt[$n]}/subdir/subdir2 echo "$output" [ "$status" -eq 0 ] uid=$((${uidrange[$n]}+$n+1)) gid=$((${gidrange[$n]}+$n+1)) echo comparing "$output" and "$uid:$gid" [ "$output" == "$uid:$gid" ] } @test "idmaps-create-mapped-image" { # This test needs "tar". if test -z "$(which tar 2> /dev/null)" ; then skip "need tar" fi if [ "$OS" != "Linux" ]; then skip "not supported on $OS" fi case "$STORAGE_DRIVER" in btrfs|overlay*|vfs|zfs) ;; *) skip "not supported by driver $STORAGE_DRIVER" ;; esac case "$STORAGE_OPTION" in *mount_program*) skip "test not supported when using mount_program" ;; esac n=5 host=2 filelist= # Create some temporary files. for i in $(seq $n) ; do createrandom "$TESTDIR"/file$i chown ${i}:${i} "$TESTDIR"/file$i filelist="$filelist file$i" done # Select some ID ranges. for i in $(seq $n) ; do uidrange[$i]=$((($RANDOM+32767)*65536)) gidrange[$i]=$((($RANDOM+32767)*65536)) done # Create a base layer using the host's mappings. run storage --debug=false create-layer --hostuidmap --hostgidmap echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] baselayer="$output" # Create an empty layer blob and apply it to the layer. dd if=/dev/zero bs=1k count=1 of="$TESTDIR"/layer.empty run storage --debug=false applydiff -f "$TESTDIR"/layer.empty $baselayer # Create a layer using the host's mappings. run storage --debug=false create-layer --hostuidmap --hostgidmap $baselayer echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] lowerlayer="$output" # Create a layer blob containing the files and apply it to the layer. tar --directory "$TESTDIR" -cvf "$TESTDIR"/layer.tar $filelist run storage --debug=false applydiff -f "$TESTDIR"/layer.tar $lowerlayer # Create an image record for this layer. run storage --debug=false create-image $lowerlayer echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] image="$output" echo image:$image # Check that we can compute the size of the image. run storage --debug=false image $image echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] size=$(grep ^Size: <<< "$output" | sed 's,^Size: ,,g') [ "$size" -ne 0 ] echo size:$size # Create containers using this image. containers= for i in $(seq $n) ; do if test $host -ne $i ; then run storage --debug=false create-container --uidmap 0:${uidrange[$i]}:$(($n+1)) --gidmap 0:${gidrange[$i]}:$(($n+1)) $image else uidrange[$host]=0 gidrange[$host]=0 run storage --debug=false create-container --hostuidmap --hostgidmap $image fi echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] container=${lines[0]} containers[$i-1]="$container" # Check that the ownerships came out right. run storage --debug=false mount "$container" echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] mount="$output" for j in $(seq $n) ; do ownerids=$(stat -c %u:%g ${mount}/file$j) echo on-disk IDs: "$ownerids" echo expected IDs: $((${uidrange[$i]}+$j)):$((${gidrange[$i]}+$j)) [ "$ownerids" = $((${uidrange[$i]}+$j)):$((${gidrange[$i]}+$j)) ] done run storage --debug=false unmount "$container" [ "$status" -eq 0 ] done # Each of the containers' layers should have a different parent layer, # all of which should be a top layer for the image. The containers # themselves have no contents at this point. declare -a parents echo containers list is \"${containers[*]}\" for container in "${containers[@]}" ; do run storage --debug=false container $container echo container "$container":"$output" [ "$status" -eq 0 ] [ "$output" != "" ] baseimage=$(grep ^Image: <<< "$output" | sed 's,^Image: ,,g') echo baseimage:"$baseimage" [ "$baseimage" = "$image" ] layer=$(grep ^Layer: <<< "$output" | sed 's,^Layer: ,,g') echo layer:"$layer" size=$(grep ^Size: <<< "$output" | sed 's,^Size: ,,g') [ "$size" -eq 0 ] echo size:$size run storage --debug=false layer $layer echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] parent=$(grep ^Parent: <<< "$output" | sed 's,^Parent: ,,g') echo parent:"$parent" parents[${#parents[*]}]="$parent" run storage --debug=false image $baseimage echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] grep "^Top Layer: $parent" <<< "$output" done nparents=$(for p in ${parents[@]} ; do echo $p ; done | sort -u | wc -l) echo nparents:$nparents [ $nparents -eq $n ] # The image should have five top layers at this point, they should all # have known sizes, and we should be able to diff them all. run storage --debug=false image $image echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] tops=$(grep '^Top Layer:' <<< "$output" | sed 's,^Top Layer: ,,g') echo tops: "$tops" ntops=$(for p in $tops; do echo $p ; done | sort -u | wc -l) echo ntops:$ntops [ $ntops -eq $n ] for p in $tops; do rm -f "$TESTDIR"/diff.tar storage --debug=false diff -u -f "$TESTDIR"/diff.tar "$p" test -s "$TESTDIR"/diff.tar expected=$(storage --debug=false layer --json $p | sed -r -e 's|.*"diff-size":([^",]*).*|\1|g') actual=$(stat -c %s "$TESTDIR"/diff.tar) echo expected diff size "$expected", got "$actual" test $actual = $expected expected=$(storage --debug=false layer --json $p | sed -r -e 's|.*"diff-digest":"?([^",]*).*|\1|g') actual=sha256:$(sha256sum "$TESTDIR"/diff.tar | sed -e 's, .*,,g') echo expected diff digest "$expected", got "$actual" test $actual = $expected done # Create a new layer based on the image. run storage --debug=false create-layer --hostuidmap --hostgidmap $lowerlayer echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] upperlayer="$output" run storage --debug=false applydiff -f "$TESTDIR"/layer.empty $upperlayer # Create an image record for the new layer. run storage --debug=false create-image $upperlayer echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] upperimage="$output" echo upperimage:$upperimage # Remove the containers and images and check that all of the layers we used got removed. for container in "${containers[@]}" ; do run storage --debug=false delete-container $container done run storage --debug=false delete-image $image run storage --debug=false delete-image $upperimage run storage --debug=false layers echo "$output" [ "$status" -eq 0 ] [ "$output" == "" ] } @test "idmaps-create-mapped-container" { if [ "$OS" != "Linux" ]; then skip "not supported on $OS" fi case "$STORAGE_DRIVER" in overlay*|vfs) ;; *) skip "${STORAGE_DRIVER}.imagestore option not supported by driver ${STORAGE_DRIVER}" ;; esac case "$STORAGE_OPTION" in *mount_program*) skip "test not supported when using mount_program" ;; esac n=5 host=2 # Create some temporary files. for i in $(seq $n) ; do createrandom "$TESTDIR"/file$i chown ${i}:${i} "$TESTDIR"/file$i done # Select some ID ranges. for i in $(seq $n) ; do uidrange[$i]=$((($RANDOM+32767)*65536)) gidrange[$i]=$((($RANDOM+32767)*65536)) done # Create a base layer using the host's mappings. run storage --debug=false --graph ${TESTDIR}/ro-root --run ${TESTDIR}/ro-runroot create-layer --hostuidmap --hostgidmap echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] baselayer="$output" # Create a layer using the host's mappings. run storage --debug=false --graph ${TESTDIR}/ro-root --run ${TESTDIR}/ro-runroot create-layer --hostuidmap --hostgidmap $baselayer echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] lowerlayer="$output" # Mount the layer. run storage --debug=false --graph ${TESTDIR}/ro-root --run ${TESTDIR}/ro-runroot mount $lowerlayer echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] lowermount="$output" # Copy the files in (host mapping, so it's fine), and set ownerships on them. cp -p "$TESTDIR"/file1 ${lowermount} cp -p "$TESTDIR"/file2 ${lowermount} cp -p "$TESTDIR"/file3 ${lowermount} cp -p "$TESTDIR"/file4 ${lowermount} cp -p "$TESTDIR"/file5 ${lowermount} # Unmount the layer. run storage --debug=false --graph ${TESTDIR}/ro-root --run ${TESTDIR}/ro-runroot unmount $lowerlayer [ "$status" -eq 0 ] # Create an image record for this layer. run storage --debug=false --graph ${TESTDIR}/ro-root --run ${TESTDIR}/ro-runroot create-image $lowerlayer echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] image="$output" echo image:$image # Check that we can compute the size of the image. run storage --debug=false --graph ${TESTDIR}/ro-root --run ${TESTDIR}/ro-runroot image $image echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] size=$(grep ^Size: <<< "$output" | sed 's,^Size: ,,g') [ "$size" -ne 0 ] echo size:$size # Done using this location directly. storage --graph ${TESTDIR}/ro-root --run ${TESTDIR}/ro-runroot shutdown # Create containers using this image. containers= for i in $(seq $n) ; do if test $host -ne $i ; then run storage --debug=false --storage-opt ${STORAGE_DRIVER}.imagestore=${TESTDIR}/ro-root create-container --uidmap 0:${uidrange[$i]}:$(($n+1)) --gidmap 0:${gidrange[$i]}:$(($n+1)) $image else uidrange[$host]=0 gidrange[$host]=0 run storage --debug=false --storage-opt ${STORAGE_DRIVER}.imagestore=${TESTDIR}/ro-root create-container --hostuidmap --hostgidmap $image fi echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] container=${lines[0]} containers[$i-1]="$container" # Check that the ownerships came out right. run storage --debug=false --storage-opt ${STORAGE_DRIVER}.imagestore=${TESTDIR}/ro-root mount "$container" echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] mount="$output" uid=$(stat -c %u ${mount}) gid=$(stat -c %g ${mount}) test ${uid}:${gid} = ${uidrange[$i]}:${gidrange[$i]} for j in $(seq $n) ; do ownerids=$(stat -c %u:%g ${mount}/file$j) echo on-disk IDs: "$ownerids" echo expected IDs: $((${uidrange[$i]}+$j)):$((${gidrange[$i]}+$j)) [ "$ownerids" = $((${uidrange[$i]}+$j)):$((${gidrange[$i]}+$j)) ] done run storage --debug=false --storage-opt ${STORAGE_DRIVER}.imagestore=${TESTDIR}/ro-root unmount "$container" [ "$status" -eq 0 ] done # Each of the containers' layers should have the same parent layer, # which should be the lone top layer for the image. The containers # themselves have no contents at this point. declare -a parents echo containers list is \"${containers[*]}\" for container in "${containers[@]}" ; do run storage --debug=false --storage-opt ${STORAGE_DRIVER}.imagestore=${TESTDIR}/ro-root container $container echo container "$container":"$output" [ "$status" -eq 0 ] [ "$output" != "" ] baseimage=$(grep ^Image: <<< "$output" | sed 's,^Image: ,,g') echo baseimage:"$baseimage" [ "$baseimage" = "$image" ] layer=$(grep ^Layer: <<< "$output" | sed 's,^Layer: ,,g') echo layer:"$layer" size=$(grep ^Size: <<< "$output" | sed 's,^Size: ,,g') [ "$size" -eq 0 ] echo size:$size run storage --debug=false --storage-opt ${STORAGE_DRIVER}.imagestore=${TESTDIR}/ro-root layer $layer echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] parent=$(grep ^Parent: <<< "$output" | sed 's,^Parent: ,,g') echo parent:"$parent" parents[${#parents[*]}]="$parent" run storage --debug=false --storage-opt ${STORAGE_DRIVER}.imagestore=${TESTDIR}/ro-root image $baseimage echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] grep "^Top Layer: $parent" <<< "$output" done nparents=$(for p in ${parents[@]} ; do echo $p ; done | sort -u | wc -l) echo nparents:$nparents [ $nparents -eq 1 ] # The image should still have only one top layer at this point. run storage --debug=false --storage-opt ${STORAGE_DRIVER}.imagestore=${TESTDIR}/ro-root image $image echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] tops=$(grep '^Top Layer:' <<< "$output" | sed 's,^Top Layer: ,,g') ntops=$(for p in $tops; do echo $p ; done | sort -u | wc -l) echo ntops:$ntops [ $ntops -eq 1 ] # Remove the containers and image and check that all of the layers we used got removed. for container in "${containers[@]}" ; do run storage --debug=false --storage-opt ${STORAGE_DRIVER}.imagestore=${TESTDIR}/ro-root delete-container $container done run storage --debug=false --graph ${TESTDIR}/ro-root --run ${TESTDIR}/ro-runroot delete-image $image run storage --debug=false --graph ${TESTDIR}/ro-root --run ${TESTDIR}/ro-runroot shutdown run storage --debug=false --storage-opt ${STORAGE_DRIVER}.imagestore=${TESTDIR}/ro-root layers echo "$output" [ "$status" -eq 0 ] [ "$output" == "" ] } @test "idmaps-create-mapped-container-shifting" { if [ "$OS" != "Linux" ]; then skip "not supported on $OS" fi case "$STORAGE_DRIVER" in overlay*) ;; *) skip "not supported by driver $STORAGE_DRIVER" ;; esac case "$STORAGE_OPTION" in *mount_program*) skip "test not supported when using mount_program" ;; esac # Create a base layer. run storage --debug=false create-layer echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] baselayer="$output" # Create the lower layer. run storage --debug=false create-layer $baselayer [ "$status" -eq 0 ] [ "$output" != "" ] lowerlayer="$output" # Mount the layer. run storage --debug=false mount $lowerlayer [ "$status" -eq 0 ] [ "$output" != "" ] lowermount="$output" # Put a file in the layer. createrandom "$lowermount"/file storage unmount $lowerlayer imagename=idmappedimage-shifting storage create-image --name=$imagename $lowerlayer } @test "idmaps-create-layer-from-another-image-store" { # This test needs "tar". if test -z "$(which tar 2> /dev/null)" ; then skip "need tar" fi if [ "$OS" != "Linux" ]; then skip "not supported on $OS" fi case "$STORAGE_DRIVER" in overlay*|vfs) ;; *) skip ".imagestore option not supported by driver ${STORAGE_DRIVER}" ;; esac case "$STORAGE_OPTION" in *mount_program*) skip "test not supported when using mount_program" ;; esac n=5 host=2 # Create some temporary files. for i in $(seq $n) ; do createrandom "$TESTDIR"/file$i chown ${i}:${i} "$TESTDIR"/file$i ln -s . $TESTDIR/subdir$i done # Use them to create some diffs. pushd $TESTDIR > /dev/null for i in $(seq $n) ; do tar cf diff${i}.tar subdir$i/ done popd > /dev/null # Create a layer using the host's mappings. run storage --graph=$TESTDIR/imagestore --debug=false create-layer --hostuidmap --hostgidmap echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] layer="$output" run storage --graph=$TESTDIR/imagestore --debug=false create-image $layer echo "$output" [ "$status" -eq 0 ] run storage --graph=$TESTDIR/newstore --storage-opt=.imagestore=$TESTDIR/imagestore --debug=false create-image $layer echo "$output" [ "$status" -eq 0 ] image="$output" for i in 0 $(seq $n) ; do uidrange[$i]=$((($RANDOM+32767)*65536)) gidrange[$i]=$((($RANDOM+32767)*65536)) done run storage --graph=$TESTDIR/newstore --storage-opt=.imagestore=$TESTDIR/imagestore --debug=false create-container --uidmap 0:${uidrange[0]}:$(($n+1)) --gidmap 0:${gidrange[0]}:$(($n+1)) $image echo "$output" [ "$status" -eq 0 ] [ "$output" != "" ] storage --graph ${TESTDIR}/imagestore shutdown storage --graph ${TESTDIR}/newstore shutdown }