github.com/moby/docker@v26.1.3+incompatible/contrib/dockerize-disk.sh (about)

     1  #!/usr/bin/env bash
     2  set -e
     3  
     4  if ! command -v qemu-nbd &> /dev/null; then
     5  	echo >&2 'error: "qemu-nbd" not found!'
     6  	exit 1
     7  fi
     8  
     9  usage() {
    10  	echo "Convert disk image to docker image"
    11  	echo ""
    12  	echo "usage: $0 image-name disk-image-file [ base-image ]"
    13  	echo "   ie: $0 cirros:0.3.3 cirros-0.3.3-x86_64-disk.img"
    14  	echo "       $0 ubuntu:cloud ubuntu-14.04-server-cloudimg-amd64-disk1.img ubuntu:14.04"
    15  }
    16  
    17  if [ "$#" -lt 2 ]; then
    18  	usage
    19  	exit 1
    20  fi
    21  
    22  CURDIR=$(pwd)
    23  
    24  image_name="${1%:*}"
    25  image_tag="${1#*:}"
    26  if [ "$image_tag" == "$1" ]; then
    27  	image_tag="latest"
    28  fi
    29  
    30  disk_image_file="$2"
    31  docker_base_image="$3"
    32  
    33  block_device=/dev/nbd0
    34  
    35  builddir=$(mktemp -d)
    36  
    37  cleanup() {
    38  	umount "$builddir/disk_image" || true
    39  	umount "$builddir/workdir" || true
    40  	qemu-nbd -d $block_device &> /dev/null || true
    41  	rm -rf $builddir
    42  }
    43  trap cleanup EXIT
    44  
    45  # Mount disk image
    46  modprobe nbd max_part=63
    47  qemu-nbd -rc ${block_device} -P 1 "$disk_image_file"
    48  mkdir "$builddir/disk_image"
    49  mount -o ro ${block_device} "$builddir/disk_image"
    50  
    51  mkdir "$builddir/workdir"
    52  mkdir "$builddir/diff"
    53  
    54  base_image_mounts=""
    55  
    56  # Unpack base image
    57  if [ -n "$docker_base_image" ]; then
    58  	mkdir -p "$builddir/base"
    59  	docker pull "$docker_base_image"
    60  	docker save "$docker_base_image" | tar -xC "$builddir/base"
    61  
    62  	image_id=$(docker inspect -f "{{.Id}}" "$docker_base_image")
    63  	while [ -n "$image_id" ]; do
    64  		mkdir -p "$builddir/base/$image_id/layer"
    65  		tar -xf "$builddir/base/$image_id/layer.tar" -C "$builddir/base/$image_id/layer"
    66  
    67  		base_image_mounts="${base_image_mounts}:$builddir/base/$image_id/layer=ro+wh"
    68  		image_id=$(docker inspect -f "{{.Parent}}" "$image_id")
    69  	done
    70  fi
    71  
    72  # Mount work directory
    73  mount -t aufs -o "br=$builddir/diff=rw${base_image_mounts},dio,xino=/dev/shm/aufs.xino" none "$builddir/workdir"
    74  
    75  # Update files
    76  cd $builddir
    77  LC_ALL=C diff -rq disk_image workdir \
    78  	| sed -re "s|Only in workdir(.*?): |DEL \1/|g;s|Only in disk_image(.*?): |ADD \1/|g;s|Files disk_image/(.+) and workdir/(.+) differ|UPDATE /\1|g" \
    79  	| while read action entry; do
    80  		case "$action" in
    81  			ADD | UPDATE)
    82  				cp -a "disk_image$entry" "workdir$entry"
    83  				;;
    84  			DEL)
    85  				rm -rf "workdir$entry"
    86  				;;
    87  			*)
    88  				echo "Error: unknown diff line: $action $entry" >&2
    89  				;;
    90  		esac
    91  	done
    92  
    93  # Pack new image
    94  new_image_id="$(for i in $(seq 1 32); do printf "%02x" $(($RANDOM % 256)); done)"
    95  mkdir -p $builddir/result/$new_image_id
    96  cd diff
    97  tar -cf $builddir/result/$new_image_id/layer.tar *
    98  echo "1.0" > $builddir/result/$new_image_id/VERSION
    99  cat > $builddir/result/$new_image_id/json <<- EOS
   100  	{ "docker_version": "1.4.1"
   101  	, "id": "$new_image_id"
   102  	, "created": "$(date -u +%Y-%m-%dT%H:%M:%S.%NZ)"
   103  EOS
   104  
   105  if [ -n "$docker_base_image" ]; then
   106  	image_id=$(docker inspect -f "{{.Id}}" "$docker_base_image")
   107  	echo ", \"parent\": \"$image_id\"" >> $builddir/result/$new_image_id/json
   108  fi
   109  
   110  echo "}" >> $builddir/result/$new_image_id/json
   111  
   112  echo "{\"$image_name\":{\"$image_tag\":\"$new_image_id\"}}" > $builddir/result/repositories
   113  
   114  cd $builddir/result
   115  
   116  # mkdir -p $CURDIR/$image_name
   117  # cp -r * $CURDIR/$image_name
   118  tar -c * | docker load