mirror of
https://github.com/flatcar/scripts.git
synced 2025-09-23 14:41:31 +02:00
feat(image_to_vm): Refactor to make adding/changing vm formats easier.
The old script was heading towards spaghetti code realm. This breaks up all the image variations such as hybrid MBR, OEM packages, etc into configuration options and small functions that actually do the work. All this is in the new vm_image_util.sh library but the command line parsing and overall procedure remains in image_to_vm.sh As part of this we gain support for putting some qemu options in a config file as well as Xen virtual machines using pygrub and pvgrub. Lots of generally unused options have been removed to simplify things and keep output file names consistent.
This commit is contained in:
parent
ad32826cbd
commit
033cf224f1
407
build_library/vm_image_util.sh
Normal file
407
build_library/vm_image_util.sh
Normal file
@ -0,0 +1,407 @@
|
||||
# Copyright (c) 2013 The CoreOS Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
# Format options. Each variable uses the form IMG_<type>_<opt>.
|
||||
# Default values use the format IMG_DEFAULT_<opt>.
|
||||
|
||||
VALID_IMG_TYPES=(
|
||||
ami
|
||||
qemu
|
||||
rackspace
|
||||
virtualbox
|
||||
vmware
|
||||
xen
|
||||
)
|
||||
|
||||
# Set at runtime to one of the above types
|
||||
VM_IMG_TYPE=DEFAULT
|
||||
|
||||
# Set at runtime to the source and destination image paths
|
||||
VM_SRC_IMG=
|
||||
VM_TMP_IMG=
|
||||
VM_TMP_DIR=
|
||||
VM_DST_IMG=
|
||||
VM_README=
|
||||
VM_NAME=
|
||||
VM_UUID=
|
||||
|
||||
## DEFAULT
|
||||
# If set to 1 use a hybrid GPT/MBR format instead of plain GPT
|
||||
IMG_DEFAULT_HYBRID_MBR=0
|
||||
|
||||
# If set install the given package name to the OEM partition
|
||||
IMG_DEFAULT_OEM_PACKAGE=
|
||||
|
||||
# Name of the target image format.
|
||||
# May be raw, vdi (virtualbox), or vmdk (vmware)
|
||||
IMG_DEFAULT_DISK_FORMAT=raw
|
||||
|
||||
# Name of the target config format, default is no config
|
||||
IMG_DEFAULT_CONF_FORMAT=
|
||||
|
||||
# Memory size to use in any config files
|
||||
IMG_DEFAULT_MEM=1024
|
||||
|
||||
## qemu
|
||||
IMG_qemu_CONF_FORMAT=qemu
|
||||
|
||||
## xen
|
||||
# Hybrid is required by pvgrub (pygrub supports GPT but we support both)
|
||||
IMG_xen_HYBRID_MBR=1
|
||||
IMG_xen_CONF_FORMAT=xl
|
||||
|
||||
## virtualbox
|
||||
IMG_virtualbox_DISK_FORMAT=vdi
|
||||
|
||||
## vmware
|
||||
IMG_vmware_DISK_FORMAT=vmdk
|
||||
IMG_vmware_CONF_FORMAT=vmx
|
||||
|
||||
## ami
|
||||
IMG_ami_HYBRID_MBR=1
|
||||
IMG_ami_OEM_PACKAGE=oem-ami
|
||||
|
||||
## rackspace
|
||||
# TODO: package doesn't exist yet
|
||||
#IMG_rackspace_OEM_PACKAGE=oem-rackspace
|
||||
|
||||
###########################################################
|
||||
|
||||
# Validate and set the vm type to use for the rest of the functions
|
||||
set_vm_type() {
|
||||
local vm_type="$1"
|
||||
local valid_type
|
||||
for valid_type in "${VALID_IMG_TYPES[@]}"; do
|
||||
if [[ "${vm_type}" == "${valid_type}" ]]; then
|
||||
VM_IMG_TYPE="${vm_type}"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
# Validate and set source vm image path
|
||||
set_vm_paths() {
|
||||
local src_dir="$1"
|
||||
local dst_dir="$2"
|
||||
local src_name="$3"
|
||||
|
||||
VM_SRC_IMG="${src_dir}/${src_name}"
|
||||
if [[ ! -f "${VM_SRC_IMG}" ]]; then
|
||||
die "Source image does not exist: $VM_SRC_IMG"
|
||||
fi
|
||||
|
||||
local dst_name="$(_src_to_dst_name "${src_name}" "_image.$(_disk_ext)")"
|
||||
VM_DST_IMG="${dst_dir}/${dst_name}"
|
||||
VM_TMP_DIR="${dst_dir}/${dst_name}.vmtmpdir"
|
||||
VM_TMP_IMG="${VM_TMP_DIR}/disk_image.bin"
|
||||
|
||||
# If src_dir happens to be in the build directory figure out the version
|
||||
# from the directory name and use it in the vm name for config files.
|
||||
VM_NAME=$(_src_to_dst_name "${src_name}" "")
|
||||
if [[ "${src_dir}" =~ /build/images/${BOARD}/\d+\.\d+\.[^/]*$ ]]; then
|
||||
VM_NAME+="-$(basename ${src_dir})"
|
||||
fi
|
||||
|
||||
VM_UUID=$(uuidgen)
|
||||
VM_README="${dst_dir}/$(_src_to_dst_name "${src_name}" ".README")"
|
||||
}
|
||||
|
||||
_get_vm_opt() {
|
||||
local opt="$1"
|
||||
local type_opt="IMG_${VM_IMG_TYPE}_${opt}"
|
||||
local default_opt="IMG_DEFAULT_${opt}"
|
||||
echo "${!type_opt:-${!default_opt}}"
|
||||
}
|
||||
|
||||
# Translate source image names to output names.
|
||||
# This keeps naming consistent across all vm types.
|
||||
_src_to_dst_name() {
|
||||
local src_img="$1"
|
||||
local suffix="$2"
|
||||
echo "${1%_image.bin}_${VM_IMG_TYPE}${suffix}"
|
||||
}
|
||||
|
||||
# Get the proper disk format extension.
|
||||
_disk_ext() {
|
||||
local disk_format=$(_get_vm_opt DISK_FORMAT)
|
||||
case ${disk_format} in
|
||||
raw) echo bin;;
|
||||
*) echo "${disk_format}";;
|
||||
esac
|
||||
}
|
||||
|
||||
# Unpack the source disk to individual partitions, optionally using an
|
||||
# alternate filesystem image for the state partition instead of the one
|
||||
# from VM_SRC_IMG. Start new image using the given disk layout.
|
||||
unpack_source_disk() {
|
||||
local disk_layout="$1"
|
||||
local alternate_state_image="$2"
|
||||
|
||||
if [[ -n "${alternate_state_image}" && ! -f "${alternate_state_image}" ]]
|
||||
then
|
||||
die "State image does not exist: $alternate_state_image"
|
||||
fi
|
||||
|
||||
info "Unpacking source image to $(relpath "${VM_TMP_DIR}")"
|
||||
|
||||
rm -rf "${VM_TMP_DIR}"
|
||||
mkdir -p "${VM_TMP_DIR}"
|
||||
|
||||
pushd "${VM_TMP_DIR}" >/dev/null
|
||||
local src_dir=$(dirname "${VM_SRC_IMG}")
|
||||
"${src_dir}/unpack_partitions.sh" "${VM_SRC_IMG}"
|
||||
popd >/dev/null
|
||||
|
||||
# Partition paths that have been unpacked from VM_SRC_IMG
|
||||
TEMP_ESP="${VM_TMP_DIR}"/part_${NUM_ESP}
|
||||
TEMP_OEM="${VM_TMP_DIR}"/part_${NUM_OEM}
|
||||
TEMP_ROOTFS="${VM_TMP_DIR}"/part_${NUM_ROOTFS_A}
|
||||
TEMP_STATE="${VM_TMP_DIR}"/part_${NUM_STATEFUL}
|
||||
# Copy the replacement STATE image if it is set
|
||||
if [[ -n "${alternate_state_image}" ]]; then
|
||||
cp "${alternate_state_image}" "${TEMP_STATE}"
|
||||
fi
|
||||
|
||||
TEMP_PMBR="${VM_TMP_DIR}"/pmbr
|
||||
dd if="${VM_SRC_IMG}" of="${TEMP_PMBR}" bs=512 count=1
|
||||
|
||||
info "Initializing new partition table..."
|
||||
TEMP_PARTITION_SCRIPT="${VM_TMP_DIR}/partition_script.sh"
|
||||
write_partition_script "${disk_layout}" "${TEMP_PARTITION_SCRIPT}"
|
||||
. "${TEMP_PARTITION_SCRIPT}"
|
||||
write_partition_table "${VM_TMP_IMG}" "${TEMP_PMBR}"
|
||||
}
|
||||
|
||||
resize_state_partition() {
|
||||
local size_in_bytes="$1"
|
||||
local size_in_sectors=$(( size_in_bytes / 512 ))
|
||||
local size_in_mb=$(( size_in_bytes / 1024 / 1024 ))
|
||||
local original_size=$(stat -c%s "${TEMP_STATE}")
|
||||
|
||||
if [[ "${original_size}" -gt "${size_in_bytes}" ]]; then
|
||||
die "Cannot resize stateful image to smaller than original."
|
||||
fi
|
||||
|
||||
info "Resizing stateful partition to ${size_in_mb}MB"
|
||||
/sbin/e2fsck -pf "${TEMP_STATE}"
|
||||
/sbin/resize2fs "${TEMP_STATE}" "${size_in_sectors}s"
|
||||
}
|
||||
|
||||
# If the current type defines a oem package install it to the given fs image.
|
||||
install_oem_package() {
|
||||
local oem_pkg=$(_get_vm_opt OEM_PACKAGE)
|
||||
local oem_mnt="${VM_TMP_DIR}/oem"
|
||||
|
||||
if [[ -z "${oem_pkg}" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
info "Installing ${oem_pkg} to OEM partition"
|
||||
mkdir -p "${oem_mnt}"
|
||||
sudo mount -o loop "${TEMP_OEM}" "${oem_mnt}"
|
||||
|
||||
# TODO(polvi): figure out how to keep portage from putting these
|
||||
# portage files on disk, we don't need or want them.
|
||||
emerge-${BOARD} --root="${oem_mnt}" --root-deps=rdeps "${oem_pkg}"
|
||||
|
||||
sudo umount "${oem_mnt}"
|
||||
rm -rf "${oem_mnt}"
|
||||
}
|
||||
|
||||
# Write the vm disk image to the target directory in the proper format
|
||||
write_vm_disk() {
|
||||
info "Writing partitions to new disk image"
|
||||
dd if="${TEMP_ROOTFS}" of="${VM_TMP_IMG}" conv=notrunc bs=512 \
|
||||
seek=$(partoffset ${VM_TMP_IMG} ${NUM_ROOTFS_A})
|
||||
dd if="${TEMP_STATE}" of="${VM_TMP_IMG}" conv=notrunc bs=512 \
|
||||
seek=$(partoffset ${VM_TMP_IMG} ${NUM_STATEFUL})
|
||||
dd if="${TEMP_ESP}" of="${VM_TMP_IMG}" conv=notrunc bs=512 \
|
||||
seek=$(partoffset ${VM_TMP_IMG} ${NUM_ESP})
|
||||
dd if="${TEMP_OEM}" of="${VM_TMP_IMG}" conv=notrunc bs=512 \
|
||||
seek=$(partoffset ${VM_TMP_IMG} ${NUM_OEM})
|
||||
|
||||
if [[ $(_get_vm_opt HYBRID_MBR) -eq 1 ]]; then
|
||||
info "Creating hybrid MBR"
|
||||
_write_hybrid_mbr "${VM_TMP_IMG}"
|
||||
fi
|
||||
|
||||
local disk_format=$(_get_vm_opt DISK_FORMAT)
|
||||
info "Writing $disk_format image to $(relpath "${VM_DST_IMG}")"
|
||||
_write_${disk_format}_disk "${VM_TMP_IMG}" "${VM_DST_IMG}"
|
||||
}
|
||||
|
||||
_write_hybrid_mbr() {
|
||||
# TODO(marineam): Switch to sgdisk
|
||||
/usr/sbin/gdisk "$1" <<EOF
|
||||
r
|
||||
h
|
||||
1
|
||||
N
|
||||
c
|
||||
Y
|
||||
N
|
||||
w
|
||||
Y
|
||||
Y
|
||||
EOF
|
||||
}
|
||||
|
||||
_write_raw_disk() {
|
||||
mv "$1" "$2"
|
||||
}
|
||||
|
||||
_write_vdi_disk() {
|
||||
sudo VBoxManage convertdd "$1" "$2"
|
||||
sudo chown $(id -un) "$2"
|
||||
}
|
||||
|
||||
_write_vmdk_disk() {
|
||||
qemu-img convert -f raw "$1" -O vmdk "$2"
|
||||
}
|
||||
|
||||
# If a config format is defined write it!
|
||||
write_vm_conf() {
|
||||
local conf_format=$(_get_vm_opt CONF_FORMAT)
|
||||
if [[ -n "${conf_format}" ]]; then
|
||||
info "Writing ${conf_format} configuration"
|
||||
_write_${conf_format}_conf "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
_write_qemu_conf() {
|
||||
local vm_mem="${1:-$(_get_vm_opt MEM)}"
|
||||
local src_name=$(basename "$VM_SRC_IMG")
|
||||
local dst_name=$(basename "$VM_DST_IMG")
|
||||
local dst_dir=$(dirname "$VM_DST_IMG")
|
||||
local conf_path="${dst_dir}/$(_src_to_dst_name "${src_name}" ".conf")"
|
||||
|
||||
# FIXME qemu 1.4/5 doesn't support these options in config files
|
||||
# Seems like submitting a patch to fix that and documenting this
|
||||
# format would be a worthy projects...
|
||||
# name=${VM_NAME}
|
||||
# uuid=${VM_UUID}
|
||||
# m=${vm_mem}
|
||||
# cpu=kvm64
|
||||
# smp=2
|
||||
|
||||
cat >"${conf_path}" <<EOF
|
||||
# qemu config file
|
||||
|
||||
# Default to KVM, fall back on full emulation
|
||||
[machine]
|
||||
accel = "kvm:tcg"
|
||||
|
||||
[drive]
|
||||
media = "disk"
|
||||
index = "0"
|
||||
#if = "virtio"
|
||||
file = "${dst_name}"
|
||||
format = "raw"
|
||||
|
||||
[net]
|
||||
type = "nic"
|
||||
vlan = "0"
|
||||
model = "virtio"
|
||||
|
||||
[net]
|
||||
type = "user"
|
||||
vlan = "0"
|
||||
hostfwd = "tcp::2222-:22"
|
||||
EOF
|
||||
|
||||
cat >"${VM_README}" <<EOF
|
||||
If you have qemu installed, you can start the image with:
|
||||
cd $(relpath "${dst_dir}")
|
||||
qemu-system-x86_64 -curses -m ${vm_mem} -readconfig "${conf_path##*/}"
|
||||
|
||||
SSH into that host with:
|
||||
ssh 127.0.0.1 -p 2222
|
||||
EOF
|
||||
}
|
||||
|
||||
# Generate the vmware config file
|
||||
# A good reference doc: http://www.sanbarrow.com/vmx.html
|
||||
_write_vmx_conf() {
|
||||
local vm_mem="${1:-$(_get_vm_opt MEM)}"
|
||||
local src_name=$(basename "$VM_SRC_IMG")
|
||||
local dst_name=$(basename "$VM_DST_IMG")
|
||||
local dst_dir=$(dirname "$VM_DST_IMG")
|
||||
local vmx_path="${dst_dir}/$(_src_to_dst_name "${src_name}" ".vmx")"
|
||||
cat >"${vmx_path}" <<EOF
|
||||
#!/usr/bin/vmware
|
||||
.encoding = "UTF-8"
|
||||
config.version = "8"
|
||||
virtualHW.version = "4"
|
||||
memsize = "${vm_mem}"
|
||||
ide0:0.present = "TRUE"
|
||||
ide0:0.fileName = "${dst_name}"
|
||||
ethernet0.present = "TRUE"
|
||||
usb.present = "TRUE"
|
||||
sound.present = "TRUE"
|
||||
sound.virtualDev = "es1371"
|
||||
displayName = "CoreOS"
|
||||
guestOS = "otherlinux"
|
||||
ethernet0.addressType = "generated"
|
||||
floppy0.present = "FALSE""
|
||||
EOF
|
||||
}
|
||||
|
||||
# Generate a new-style (xl) Xen config file for both pvgrub and pygrub
|
||||
_write_xl_conf() {
|
||||
local vm_mem="${1:-$(_get_vm_opt MEM)}"
|
||||
local src_name=$(basename "$VM_SRC_IMG")
|
||||
local dst_name=$(basename "$VM_DST_IMG")
|
||||
local dst_dir=$(dirname "$VM_DST_IMG")
|
||||
local pygrub="${dst_dir}/$(_src_to_dst_name "${src_name}" "_pygrub.cfg")"
|
||||
local pvgrub="${dst_dir}/$(_src_to_dst_name "${src_name}" "_pvgrub.cfg")"
|
||||
|
||||
# Set up the few differences between pygrub and pvgrub
|
||||
echo '# Xen PV config using pygrub' > "${pygrub}"
|
||||
echo 'bootloader = "pygrub"' >> "${pygrub}"
|
||||
|
||||
echo '# Xen PV config using pvgrub' > "${pvgrub}"
|
||||
echo 'kernel = "/usr/lib/xen/boot/pv-grub-x86_64.gz"' >> "${pvgrub}"
|
||||
echo 'extra = "(hd0,0)/boot/grub/menu.lst"' >> "${pvgrub}"
|
||||
|
||||
# The rest is the same
|
||||
tee -a "${pygrub}" >> "${pvgrub}" <<EOF
|
||||
|
||||
builder = "generic"
|
||||
name = "${VM_NAME}"
|
||||
uuid = "${VM_UUID}"
|
||||
|
||||
memory = "${vm_mem}"
|
||||
vcpus = 2
|
||||
# TODO(marineam): networking...
|
||||
vif = [ ]
|
||||
disk = [ '${dst_name},raw,xvda' ]
|
||||
EOF
|
||||
|
||||
cat > "${VM_README}" <<EOF
|
||||
If this is a Xen Dom0 host with pygrub you can start the vm with:
|
||||
cd $(relpath "${dst_dir}")
|
||||
xl create -c "${pygrub##*/}"
|
||||
|
||||
Or with pvgrub instead:
|
||||
xl create -c "${pvgrub##*/}"
|
||||
|
||||
Detach from the console with ^] and reattach with:
|
||||
xl console ${VM_NAME}
|
||||
|
||||
Kill the vm with:
|
||||
xl destroy ${VM_NAME}
|
||||
EOF
|
||||
}
|
||||
|
||||
vm_cleanup() {
|
||||
info "Cleaning up temporary files"
|
||||
rm -rf "${VM_TMP_DIR}"
|
||||
}
|
||||
|
||||
print_readme() {
|
||||
if [[ -f "${VM_README}" ]]; then
|
||||
cat "${VM_README}"
|
||||
fi
|
||||
}
|
@ -977,6 +977,13 @@ reinterpret_path_for_chroot() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Get the relative path between two locations. Handy for printing paths to
|
||||
# the user that will usually make sense both inside and outside the chroot.
|
||||
relpath() {
|
||||
local py='import sys, os; print os.path.relpath(sys.argv[1], sys.argv[2])'
|
||||
python2 -c "${py}" "${1}" "${2:-.}"
|
||||
}
|
||||
|
||||
emerge_custom_kernel() {
|
||||
local install_root=$1
|
||||
local root=/build/${FLAGS_board}
|
||||
|
213
image_to_vm.sh
213
image_to_vm.sh
@ -4,15 +4,18 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
# Script to convert the output of build_image.sh to a VMware image and write a
|
||||
# corresponding VMware config file.
|
||||
# Script to convert the output of build_image.sh to a usable virtual machine
|
||||
# disk image, supporting a variety of different targets.
|
||||
|
||||
|
||||
|
||||
# Helper scripts should be run from the same location as this script.
|
||||
SCRIPT_ROOT=$(dirname "$(readlink -f "$0")")
|
||||
. "${SCRIPT_ROOT}/common.sh" || exit 1
|
||||
. "${SCRIPT_ROOT}/build_library/disk_layout_util.sh" || exit 1
|
||||
. "${SCRIPT_ROOT}/build_library/build_common.sh" || exit 1
|
||||
. "${SCRIPT_ROOT}/build_library/build_image_util.sh" || exit 1
|
||||
. "${BUILD_LIBRARY_DIR}/disk_layout_util.sh" || exit 1
|
||||
. "${BUILD_LIBRARY_DIR}/build_common.sh" || exit 1
|
||||
. "${BUILD_LIBRARY_DIR}/build_image_util.sh" || exit 1
|
||||
. "${BUILD_LIBRARY_DIR}/vm_image_util.sh" || exit 1
|
||||
|
||||
# Need to be inside the chroot to load chromeos-common.sh
|
||||
assert_inside_chroot
|
||||
@ -33,15 +36,13 @@ DEFINE_boolean prod $FLAGS_FALSE \
|
||||
# behavior from image_to_usb.sh
|
||||
DEFINE_boolean force_copy ${FLAGS_FALSE} "Always rebuild test image"
|
||||
DEFINE_string format "qemu" \
|
||||
"Output format, either xen, qemu, vmware or virtualbox"
|
||||
"Output format, one of: ${VALID_IMG_TYPES[*]}"
|
||||
DEFINE_string from "" \
|
||||
"Directory containing rootfs.image and mbr.image"
|
||||
DEFINE_string disk_layout "vm" \
|
||||
"The disk layout type to use for this image."
|
||||
DEFINE_boolean make_vmx ${FLAGS_TRUE} \
|
||||
"Create a vmx file for use with vmplayer (vmware only)."
|
||||
DEFINE_integer mem "${DEFAULT_MEM}" \
|
||||
"Memory size for the vm config in MBs (vmware only)."
|
||||
"Memory size for the vm config in MBs."
|
||||
DEFINE_string state_image "" \
|
||||
"Stateful partition image (defaults to creating new statful partition)"
|
||||
DEFINE_boolean test_image "${FLAGS_FALSE}" \
|
||||
@ -50,23 +51,6 @@ DEFINE_boolean prod_image "${FLAGS_FALSE}" \
|
||||
"Copies normal image to ${COREOS_OFFICIAL_IMAGE_NAME}, modifies it for test."
|
||||
DEFINE_string to "" \
|
||||
"Destination folder for VM output file(s)"
|
||||
DEFINE_string vbox_disk "${DEFAULT_VBOX_DISK}" \
|
||||
"Filename for the output disk (virtualbox only)."
|
||||
DEFINE_string vmdk "${DEFAULT_VMDK}" \
|
||||
"Filename for the vmware disk image (vmware only)."
|
||||
DEFINE_string vmx "${DEFAULT_VMX}" \
|
||||
"Filename for the vmware config (vmware only)."
|
||||
|
||||
# The following arguments are ignored.
|
||||
# They are here as part of a transition for CL #29931 beacuse the buildbots
|
||||
# specify these arguments.
|
||||
DEFINE_integer vdisk_size 3072 \
|
||||
"virtual disk size in MBs."
|
||||
DEFINE_boolean full "${FLAGS_FALSE}" "Build full image with all partitions."
|
||||
DEFINE_integer rootfs_partition_size 1024 \
|
||||
"rootfs parition size in MBs."
|
||||
DEFINE_integer statefulfs_size 2048 \
|
||||
"Stateful partition size in MBs."
|
||||
|
||||
# Parse command line
|
||||
FLAGS "$@" || exit 1
|
||||
@ -75,6 +59,10 @@ eval set -- "${FLAGS_ARGV}"
|
||||
# Die on any errors.
|
||||
switch_to_strict_mode
|
||||
|
||||
if ! set_vm_type "${FLAGS_format}"; then
|
||||
die_notrace "Invalid format: ${FLAGS_format}"
|
||||
fi
|
||||
|
||||
if [ -z "${FLAGS_board}" ] ; then
|
||||
die_notrace "--board is required."
|
||||
fi
|
||||
@ -92,164 +80,43 @@ if [ -z "${FLAGS_to}" ] ; then
|
||||
FLAGS_to="${FLAGS_from}"
|
||||
fi
|
||||
|
||||
if [ ${FLAGS_prod_image} -eq ${FLAGS_TRUE} ]; then
|
||||
SRC_IMAGE="${FLAGS_from}/${COREOS_PRODUCTION_IMAGE_NAME}"
|
||||
elif [ ${FLAGS_test_image} -eq ${FLAGS_TRUE} ]; then
|
||||
SRC_IMAGE="${FLAGS_from}/${CHROMEOS_TEST_IMAGE_NAME}"
|
||||
else
|
||||
# Use the standard image
|
||||
SRC_IMAGE="${FLAGS_from}/${CHROMEOS_IMAGE_NAME}"
|
||||
fi
|
||||
|
||||
locate_gpt
|
||||
legacy_offset_size_export ${SRC_IMAGE}
|
||||
|
||||
# Memory units are in MBs
|
||||
TEMP_IMG="$(dirname "${SRC_IMAGE}")/vm_temp_image.bin"
|
||||
|
||||
# If we're not building for VMWare, don't build the vmx
|
||||
if [ "${FLAGS_format}" != "vmware" ]; then
|
||||
FLAGS_make_vmx="${FLAGS_FALSE}"
|
||||
fi
|
||||
|
||||
# Convert args to paths. Need eval to un-quote the string so that shell
|
||||
# chars like ~ are processed; just doing FOO=`readlink -f $FOO` won't work.
|
||||
FLAGS_from=`eval readlink -f $FLAGS_from`
|
||||
FLAGS_to=`eval readlink -f $FLAGS_to`
|
||||
|
||||
# Split apart the partitions and make some new ones
|
||||
TEMP_DIR=$(mktemp -d)
|
||||
pushd "${TEMP_DIR}" >/dev/null
|
||||
"${FLAGS_from}/unpack_partitions.sh" "${SRC_IMAGE}"
|
||||
popd >/dev/null
|
||||
|
||||
# Fix the kernel command line
|
||||
TEMP_ESP="${TEMP_DIR}"/part_${NUM_ESP}
|
||||
TEMP_OEM="${TEMP_DIR}"/part_${NUM_OEM}
|
||||
TEMP_ROOTFS="${TEMP_DIR}"/part_${NUM_ROOTFS_A}
|
||||
TEMP_STATE="${TEMP_DIR}"/part_${NUM_STATEFUL}
|
||||
if [ -n "${FLAGS_state_image}" ]; then
|
||||
TEMP_STATE="${FLAGS_state_image}"
|
||||
if [ ${FLAGS_prod_image} -eq ${FLAGS_TRUE} ]; then
|
||||
set_vm_paths "${FLAGS_from}" "${FLAGS_to}" "${COREOS_PRODUCTION_IMAGE_NAME}"
|
||||
elif [ ${FLAGS_test_image} -eq ${FLAGS_TRUE} ]; then
|
||||
set_vm_paths "${FLAGS_from}" "${FLAGS_to}" "${CHROMEOS_TEST_IMAGE_NAME}"
|
||||
else
|
||||
STATEFUL_SIZE_BYTES=$(get_filesystem_size "${FLAGS_disk_layout}" ${NUM_STATEFUL})
|
||||
STATEFUL_SIZE_MEGABYTES=$(( STATEFUL_SIZE_BYTES / 1024 / 1024 ))
|
||||
original_image_size=$(stat -c%s "${TEMP_STATE}")
|
||||
if [ "${original_image_size}" -gt "${STATEFUL_SIZE_BYTES}" ]; then
|
||||
die "Cannot resize stateful image to smaller than original. Exiting."
|
||||
# Use the standard image
|
||||
set_vm_paths "${FLAGS_from}" "${FLAGS_to}" "${CHROMEOS_IMAGE_NAME}"
|
||||
fi
|
||||
|
||||
echo "Resizing stateful partition to ${STATEFUL_SIZE_MEGABYTES}MB"
|
||||
# Extend the original file size to the new size.
|
||||
sudo e2fsck -pf "${TEMP_STATE}"
|
||||
sudo resize2fs "${TEMP_STATE}" ${STATEFUL_SIZE_MEGABYTES}M
|
||||
fi
|
||||
locate_gpt
|
||||
legacy_offset_size_export ${VM_SRC_IMG}
|
||||
|
||||
# handle OEM stuff if needed
|
||||
TEMP_OEM_MNT="${TEMP_DIR}"/oem_mnt
|
||||
mkdir -p $TEMP_OEM_MNT
|
||||
sudo mount -o loop ${TEMP_OEM} ${TEMP_OEM_MNT}
|
||||
# Make sure things are cleaned up on failure
|
||||
trap vm_cleanup EXIT
|
||||
|
||||
# oem hacks
|
||||
if [ "${FLAGS_format}" == "ami" ]; then
|
||||
# TODO(polvi): figure out how to keep portage from putting these
|
||||
# portage files on disk, we don't need or want them.
|
||||
emerge-${BOARD} --root="${TEMP_OEM_MNT}" --root-deps=rdeps oem-ami
|
||||
elif [ "${FLAGS_format}" == "rackspace" ]; then
|
||||
emerge-${BOARD} --root="${TEMP_OEM_MNT}" --root-deps=rdeps oem-rackspace
|
||||
fi
|
||||
# Unpack image, using alternate state image if defined
|
||||
# Resize to use all available space in new disk layout
|
||||
STATEFUL_SIZE=$(get_filesystem_size "${FLAGS_disk_layout}" ${NUM_STATEFUL})
|
||||
unpack_source_disk "${FLAGS_disk_layout}" "${FLAGS_state_image}"
|
||||
resize_state_partition "${STATEFUL_SIZE}"
|
||||
|
||||
sudo umount ${TEMP_OEM_MNT}
|
||||
rm -rf ${TEMP_OEM_MNT}
|
||||
# Optionally install any OEM packages
|
||||
install_oem_package
|
||||
|
||||
# Changes done, glue it together
|
||||
write_vm_disk
|
||||
write_vm_conf "${FLAGS_mem}"
|
||||
|
||||
TEMP_PMBR="${TEMP_DIR}"/pmbr
|
||||
dd if="${SRC_IMAGE}" of="${TEMP_PMBR}" bs=512 count=1
|
||||
vm_cleanup
|
||||
trap - EXIT
|
||||
|
||||
# Set up a new partition table
|
||||
PARTITION_SCRIPT_PATH=$( tempfile )
|
||||
write_partition_script "${FLAGS_disk_layout}" "${PARTITION_SCRIPT_PATH}"
|
||||
. "${PARTITION_SCRIPT_PATH}"
|
||||
write_partition_table "${TEMP_IMG}" "${TEMP_PMBR}"
|
||||
rm "${PARTITION_SCRIPT_PATH}"
|
||||
|
||||
# Copy into the partition parts of the file
|
||||
dd if="${TEMP_ROOTFS}" of="${TEMP_IMG}" conv=notrunc bs=512 \
|
||||
seek=$(partoffset ${TEMP_IMG} ${NUM_ROOTFS_A})
|
||||
dd if="${TEMP_STATE}" of="${TEMP_IMG}" conv=notrunc bs=512 \
|
||||
seek=$(partoffset ${TEMP_IMG} ${NUM_STATEFUL})
|
||||
dd if="${TEMP_ESP}" of="${TEMP_IMG}" conv=notrunc bs=512 \
|
||||
seek=$(partoffset ${TEMP_IMG} ${NUM_ESP})
|
||||
dd if="${TEMP_OEM}" of="${TEMP_IMG}" conv=notrunc bs=512 \
|
||||
seek=$(partoffset ${TEMP_IMG} ${NUM_OEM})
|
||||
|
||||
echo Creating final image
|
||||
# Convert image to output format
|
||||
if [ "${FLAGS_format}" = "virtualbox" -o "${FLAGS_format}" = "qemu" \
|
||||
-o "${FLAGS_format}" = "xen" ]; then
|
||||
if [ "${FLAGS_format}" = "virtualbox" ]; then
|
||||
sudo VBoxManage convertdd "${TEMP_IMG}" "${FLAGS_to}/${FLAGS_vbox_disk}"
|
||||
else
|
||||
mv ${TEMP_IMG} ${FLAGS_to}/${DEFAULT_QEMU_IMAGE}
|
||||
fi
|
||||
elif [ "${FLAGS_format}" = "vmware" ]; then
|
||||
qemu-img convert -f raw "${TEMP_IMG}" \
|
||||
-O vmdk "${FLAGS_to}/${FLAGS_vmdk}"
|
||||
elif [ "${FLAGS_format}" = "ami" ]; then
|
||||
/usr/sbin/gdisk ${TEMP_IMG} <<EOF
|
||||
r
|
||||
h
|
||||
1
|
||||
N
|
||||
c
|
||||
Y
|
||||
N
|
||||
w
|
||||
Y
|
||||
Y
|
||||
EOF
|
||||
mv ${TEMP_IMG} ${FLAGS_to}/${DEFAULT_QEMU_IMAGE/qemu/ami}
|
||||
elif [ "${FLAGS_format}" = "rackspace" ]; then
|
||||
mv ${TEMP_IMG} ${FLAGS_to}/${DEFAULT_QEMU_IMAGE/qemu/rackspace}
|
||||
else
|
||||
die_notrace "Invalid format: ${FLAGS_format}"
|
||||
fi
|
||||
|
||||
rm -rf "${TEMP_DIR}" "${TEMP_IMG}"
|
||||
if [ -z "${FLAGS_state_image}" ]; then
|
||||
rm -f "${STATE_IMAGE}"
|
||||
fi
|
||||
|
||||
echo "Created image at ${FLAGS_to}"
|
||||
|
||||
# Generate the vmware config file
|
||||
# A good reference doc: http://www.sanbarrow.com/vmx.html
|
||||
VMX_CONFIG="#!/usr/bin/vmware
|
||||
.encoding = \"UTF-8\"
|
||||
config.version = \"8\"
|
||||
virtualHW.version = \"4\"
|
||||
memsize = \"${FLAGS_mem}\"
|
||||
ide0:0.present = \"TRUE\"
|
||||
ide0:0.fileName = \"${FLAGS_vmdk}\"
|
||||
ethernet0.present = \"TRUE\"
|
||||
usb.present = \"TRUE\"
|
||||
sound.present = \"TRUE\"
|
||||
sound.virtualDev = \"es1371\"
|
||||
displayName = \"Chromium OS\"
|
||||
guestOS = \"otherlinux\"
|
||||
ethernet0.addressType = \"generated\"
|
||||
floppy0.present = \"FALSE\""
|
||||
|
||||
if [[ "${FLAGS_make_vmx}" = "${FLAGS_TRUE}" ]]; then
|
||||
echo "${VMX_CONFIG}" > "${FLAGS_to}/${FLAGS_vmx}"
|
||||
echo "Wrote the following config to: ${FLAGS_to}/${FLAGS_vmx}"
|
||||
echo "${VMX_CONFIG}"
|
||||
fi
|
||||
|
||||
|
||||
if [ "${FLAGS_format}" == "qemu" ]; then
|
||||
echo "If you have qemu-kvm installed, you can start the image by:"
|
||||
echo "qemu-kvm -m ${FLAGS_mem} -curses -pidfile /tmp/kvm.pid -net nic,model=virtio \\"
|
||||
echo " -net user,hostfwd=tcp::2222-:22 -hda ${FLAGS_to}/${DEFAULT_QEMU_IMAGE}"
|
||||
echo "SSH into the host with:"
|
||||
echo "ssh 127.0.0.1 -p 2222"
|
||||
fi
|
||||
# Ready to set sail!
|
||||
okboat
|
||||
command_completed
|
||||
print_readme
|
||||
|
Loading…
x
Reference in New Issue
Block a user