2015-02-18 11:22:43 +01:00
|
|
|
#!/usr/bin/env bash
|
2015-03-17 10:27:04 +01:00
|
|
|
#set -xu
|
2015-02-18 11:22:43 +01:00
|
|
|
|
|
|
|
|
error() {
|
|
|
|
|
local msg="${1}"
|
2015-04-17 16:13:21 +02:00
|
|
|
echo "==> ERROR: ${msg}"
|
2015-02-18 11:22:43 +01:00
|
|
|
exit 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
usage() {
|
2016-12-01 13:58:40 +01:00
|
|
|
echo "Usage: ${0} IMAGE [BOX] [Vagrantfile.add]"
|
2015-02-18 11:22:43 +01:00
|
|
|
echo
|
|
|
|
|
echo "Package a qcow2 image into a vagrant-libvirt reusable box"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Print the image's backing file
|
|
|
|
|
backing(){
|
|
|
|
|
local img=${1}
|
2015-02-26 09:46:04 +01:00
|
|
|
qemu-img info "$img" | grep 'backing file:' | cut -d ':' -f2
|
2015-02-18 11:22:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Rebase the image
|
|
|
|
|
rebase(){
|
|
|
|
|
local img=${1}
|
2015-02-26 09:46:04 +01:00
|
|
|
qemu-img rebase -p -b "" "$img"
|
2015-02-18 11:22:43 +01:00
|
|
|
[[ "$?" -ne 0 ]] && error "Error during rebase"
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-19 08:58:49 +01:00
|
|
|
# Is absolute path
|
|
|
|
|
isabspath(){
|
|
|
|
|
local path=${1}
|
2015-02-26 09:46:04 +01:00
|
|
|
[[ "$path" =~ ^/.* ]]
|
2015-02-19 08:58:49 +01:00
|
|
|
}
|
|
|
|
|
|
2016-12-01 12:42:55 +01:00
|
|
|
if [ -z "$1" ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
|
2015-02-18 11:22:43 +01:00
|
|
|
usage
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
2015-02-26 09:46:04 +01:00
|
|
|
IMG=$(readlink -e "$1")
|
|
|
|
|
[[ "$?" -ne 0 ]] && error "'$1': No such image"
|
2015-02-18 11:22:43 +01:00
|
|
|
|
2015-02-26 09:46:04 +01:00
|
|
|
IMG_DIR=$(dirname "$IMG")
|
|
|
|
|
IMG_BASENAME=$(basename "$IMG")
|
2015-02-18 11:22:43 +01:00
|
|
|
|
2015-02-26 09:46:04 +01:00
|
|
|
BOX=${2:-}
|
2015-02-18 11:22:43 +01:00
|
|
|
# If no box name is supplied infer one from image name
|
2015-02-26 09:46:04 +01:00
|
|
|
if [[ -z "$BOX" ]]; then
|
2015-02-18 11:22:43 +01:00
|
|
|
BOX_NAME=${IMG_BASENAME%.*}
|
|
|
|
|
BOX=$BOX_NAME.box
|
|
|
|
|
else
|
2015-02-26 09:46:04 +01:00
|
|
|
BOX_NAME=$(basename "${BOX%.*}")
|
2015-02-18 11:22:43 +01:00
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
[[ -f "$BOX" ]] && error "'$BOX': Already exists"
|
|
|
|
|
|
|
|
|
|
CWD=$(pwd)
|
2015-02-26 09:46:04 +01:00
|
|
|
TMP_DIR="$CWD/_tmp_package"
|
|
|
|
|
TMP_IMG="$TMP_DIR/box.img"
|
2015-02-18 11:22:43 +01:00
|
|
|
|
2015-02-26 09:46:04 +01:00
|
|
|
mkdir -p "$TMP_DIR"
|
2015-02-18 11:22:43 +01:00
|
|
|
|
2015-05-18 09:30:29 +02:00
|
|
|
[[ ! -r "$IMG" ]] && error "'$IMG': Permission denied"
|
2015-03-17 10:27:04 +01:00
|
|
|
|
2016-12-01 13:58:40 +01:00
|
|
|
if [ -n "$3" ] && [ -r "$3" ]; then
|
|
|
|
|
VAGRANTFILE_ADD="$(cat $3)"
|
|
|
|
|
fi
|
|
|
|
|
|
2015-02-18 11:22:43 +01:00
|
|
|
# We move / copy (when the image has master) the image to the tempdir
|
|
|
|
|
# ensure that it's moved back / removed again
|
2015-02-26 09:46:04 +01:00
|
|
|
if [[ -n $(backing "$IMG") ]]; then
|
2015-02-18 11:22:43 +01:00
|
|
|
echo "==> Image has backing image, copying image and rebasing ..."
|
|
|
|
|
trap "rm -rf $TMP_DIR" EXIT
|
2015-02-26 09:46:04 +01:00
|
|
|
cp "$IMG" "$TMP_IMG"
|
|
|
|
|
rebase "$TMP_IMG"
|
2015-02-18 11:22:43 +01:00
|
|
|
else
|
2015-04-17 16:13:21 +02:00
|
|
|
if fuser -s "$IMG"; then
|
|
|
|
|
error "Image '$IMG_BASENAME' is used by another process"
|
|
|
|
|
fi
|
|
|
|
|
|
2015-03-17 10:27:04 +01:00
|
|
|
# move the image to get a speed-up and use less space on disk
|
2015-02-26 09:46:04 +01:00
|
|
|
trap 'mv "$TMP_IMG" "$IMG"; rm -rf "$TMP_DIR"' EXIT
|
|
|
|
|
mv "$IMG" "$TMP_IMG"
|
2015-02-18 11:22:43 +01:00
|
|
|
fi
|
|
|
|
|
|
2015-02-26 09:46:04 +01:00
|
|
|
cd "$TMP_DIR"
|
2015-02-18 11:22:43 +01:00
|
|
|
|
2015-10-05 13:43:38 -04:00
|
|
|
#Using the awk int function here to truncate the virtual image size to an
|
|
|
|
|
#integer since the fog-libvirt library does not seem to properly handle
|
|
|
|
|
#floating point.
|
2017-03-20 13:23:48 +00:00
|
|
|
IMG_SIZE=$(qemu-img info --output=json "$TMP_IMG" | awk '/virtual-size/{s=int($2)/(1024^3); print (s == int(s)) ? s : int(s)+1 }')
|
2015-10-09 15:55:03 -04:00
|
|
|
|
|
|
|
|
echo "{$IMG_SIZE}"
|
2015-02-18 11:22:43 +01:00
|
|
|
|
|
|
|
|
cat > metadata.json <<EOF
|
|
|
|
|
{
|
|
|
|
|
"provider": "libvirt",
|
|
|
|
|
"format": "qcow2",
|
|
|
|
|
"virtual_size": ${IMG_SIZE}
|
|
|
|
|
}
|
|
|
|
|
EOF
|
|
|
|
|
|
|
|
|
|
cat > Vagrantfile <<EOF
|
|
|
|
|
Vagrant.configure("2") do |config|
|
|
|
|
|
|
|
|
|
|
config.vm.provider :libvirt do |libvirt|
|
|
|
|
|
|
|
|
|
|
libvirt.driver = "kvm"
|
|
|
|
|
libvirt.host = ""
|
|
|
|
|
libvirt.connect_via_ssh = false
|
|
|
|
|
libvirt.storage_pool_name = "default"
|
|
|
|
|
|
|
|
|
|
end
|
2016-12-01 13:58:40 +01:00
|
|
|
|
|
|
|
|
${VAGRANTFILE_ADD:-}
|
2015-02-18 11:22:43 +01:00
|
|
|
end
|
|
|
|
|
EOF
|
|
|
|
|
|
|
|
|
|
echo "==> Creating box, tarring and gzipping"
|
|
|
|
|
|
2017-03-20 04:26:52 -03:00
|
|
|
tar cvzf "$BOX" -S --totals ./metadata.json ./Vagrantfile ./box.img
|
2015-02-18 11:22:43 +01:00
|
|
|
|
2015-02-19 08:58:49 +01:00
|
|
|
# if box is in tmpdir move it to CWD before removing tmpdir
|
2015-02-26 09:46:04 +01:00
|
|
|
if ! isabspath "$BOX"; then
|
|
|
|
|
mv "$BOX" "$CWD"
|
2015-02-19 08:58:49 +01:00
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
echo "==> ${BOX} created"
|
2015-02-18 11:22:43 +01:00
|
|
|
echo "==> You can now add the box:"
|
|
|
|
|
echo "==> 'vagrant box add ${BOX} --name ${BOX_NAME}'"
|