mirror of
https://github.com/flatcar/scripts.git
synced 2026-05-04 19:56:32 +02:00
Merge pull request #55 from marineam/vm
feat(image_to_vm): Refactor to make adding/changing vm formats easier.
This commit is contained in:
commit
b2b23fdaf4
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."
|
||||
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
|
||||
# Use the standard image
|
||||
set_vm_paths "${FLAGS_from}" "${FLAGS_to}" "${CHROMEOS_IMAGE_NAME}"
|
||||
fi
|
||||
|
||||
# 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}
|
||||
locate_gpt
|
||||
legacy_offset_size_export ${VM_SRC_IMG}
|
||||
|
||||
# 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
|
||||
# Make sure things are cleaned up on failure
|
||||
trap vm_cleanup EXIT
|
||||
|
||||
sudo umount ${TEMP_OEM_MNT}
|
||||
rm -rf ${TEMP_OEM_MNT}
|
||||
# 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}"
|
||||
|
||||
# Optionally install any OEM packages
|
||||
install_oem_package
|
||||
|
||||
TEMP_PMBR="${TEMP_DIR}"/pmbr
|
||||
dd if="${SRC_IMAGE}" of="${TEMP_PMBR}" bs=512 count=1
|
||||
# Changes done, glue it together
|
||||
write_vm_disk
|
||||
write_vm_conf "${FLAGS_mem}"
|
||||
|
||||
# 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}"
|
||||
vm_cleanup
|
||||
trap - EXIT
|
||||
|
||||
# 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