diff --git a/build_library/qemu_template.sh b/build_library/qemu_template.sh index 7d5b352e36..6f1108b33f 100755 --- a/build_library/qemu_template.sh +++ b/build_library/qemu_template.sh @@ -11,8 +11,13 @@ VM_CDROM= VM_NCPUS="`grep -c ^processor /proc/cpuinfo`" SSH_PORT=2222 SSH_KEYS="" +CONFIG_FILE="" +CONFIG_IMAGE="" +SAFE_ARGS=0 USAGE="Usage: $0 [-a authorized_keys] [--] [qemu options...] Options: + -u FILE Cloudinit user-data as either a cloud config or script. + -c FILE Config drive as an iso or fat filesystem image. -a FILE SSH public keys for login access. [~/.ssh/id_{dsa,rsa}.pub] -p PORT The port on localhost to map to the VM's sshd. [2222] -s Safe settings: single simple cpu, ide disks. @@ -29,57 +34,103 @@ Any arguments after -a and -p will be passed through to qemu, -- may be used as an explicit separator. See the qemu(1) man page for more details. " -safe_args=0 -script_args=1 -while getopts ":a:p:svh" OPTION -do - case $OPTION in - a) SSH_KEYS="$OPTARG" ;; - p) SSH_PORT="$OPTARG" ;; - s) safe_args=1 ;; - v) set -x ;; - h) echo "$USAGE"; exit ;; - ?) break ;; - esac - script_args=$OPTIND -done - -shift $((script_args - 1)) -[ "$1" = "--" ] && shift - - -METADATA=$(mktemp -t -d coreos-meta-data.XXXXXXXXXX) -if [ $? -ne 0 ] || [ ! -d "$METADATA" ]; then - echo "$0: mktemp -d failed!" >&2 - exit 1 -fi -trap "rm -rf '$METADATA'" EXIT - - -# Do our best to create an authorized_keys file -if [ -n "$SSH_KEYS" ]; then - if [ ! -f "$SSH_KEYS" ]; then - echo "$0: SSH keys file not found: $SSH_KEYS" >&2 - exit 1 - elif ! cp "$SSH_KEYS" "${METADATA}/authorized_keys"; then - echo "$0: Failed to copy SSH keys from $SSH_KEYS" >&2 +check_conflict() { + if [ -n "${CONFIG_FILE}${CONFIG_IMAGE}${SSH_KEYS}" ]; then + echo "The -u -c and -a options cannot be combined!" >&2 exit 1 fi -else - # Nothing provided, try fetching from ssh-agent and the local fs +} + +while [ $# -ge 1 ]; do + case "$1" in + -u|-user-data) + check_conflict + CONFIG_FILE="$2" + shift 2 ;; + -c|-config-drive) + check_conflict + CONFIG_IMAGE="$2" + shift 2 ;; + -a|-authorized-keys) + check_conflict + SSH_KEYS="$2" + shift 2 ;; + -p|-ssh-port) + SSH_PORT="$2" + shift 2 ;; + -s|-safe) + SAFE_ARGS=1 + shift ;; + -v|-verbose) + set -x + shift ;; + -h|-help|--help) + echo "$USAGE" + exit ;; + --) + shift + break ;; + *) + break ;; + esac +done + + +find_ssh_keys() { if [ -S "$SSH_AUTH_SOCK" ]; then - ssh-add -L >> "${METADATA}/authorized_keys" + ssh-add -L fi for default_key in ~/.ssh/id_*.pub; do if [ ! -f "$default_key" ]; then continue fi - cat "$default_key" >> "${METADATA}/authorized_keys" + cat "$default_key" done +} + +write_ssh_keys() { + echo "#cloud-config" + echo "ssh_authorized_keys:" + sed -e 's/^/ - /' +} + + +if [ -z "${CONFIG_IMAGE}" ]; then + CONFIG_DRIVE=$(mktemp -t -d coreos-configdrive.XXXXXXXXXX) + if [ $? -ne 0 ] || [ ! -d "$CONFIG_DRIVE" ]; then + echo "$0: mktemp -d failed!" >&2 + exit 1 + fi + trap "rm -rf '$CONFIG_DRIVE'" EXIT + mkdir -p "${CONFIG_DRIVE}/openstack/latest" + + + if [ -n "$SSH_KEYS" ]; then + if [ ! -f "$SSH_KEYS" ]; then + echo "$0: SSH keys file not found: $SSH_KEYS" >&2 + exit 1 + fi + SSH_KEYS_TEXT=$(cat "$SSH_KEYS") + if [ $? -ne 0 ] || [ -z "$SSH_KEYS_TEXT" ]; then + echo "$0: Failed to read SSH keys from $SSH_KEYS" >&2 + exit 1 + fi + echo "$SSH_KEYS_TEXT" | write_ssh_keys > \ + "${CONFIG_DRIVE}/openstack/latest/user_data" + elif [ -n "${CONFIG_FILE}" ]; then + cp "${CONFIG_FILE}" "${CONFIG_DRIVE}/openstack/latest/user_data" + if [ $? -ne 0 ]; then + echo "$0: Failed to copy cloudinit file from $CONFIG_FILE" >&2 + exit 1 + fi + else + find_ssh_keys | write_ssh_keys > \ + "${CONFIG_DRIVE}/openstack/latest/user_data" + fi fi # Start assembling our default command line arguments -if [ "${safe_args}" -eq 1 ]; then +if [ "${SAFE_ARGS}" -eq 1 ]; then disk_type="ide" else disk_type="virtio" @@ -87,6 +138,17 @@ else set -- -cpu host -smp "${VM_NCPUS}" "$@" fi +# ${CONFIG_DRIVE} or ${CONFIG_IMAGE} will be mounted in CoreOS as /media/configdrive +if [ -n "${CONFIG_DRIVE}" ]; then + set -- \ + -fsdev local,id=conf,security_model=none,readonly,path="${CONFIG_DRIVE}" \ + -device virtio-9p-pci,fsdev=conf,mount_tag=config-2 "$@" +fi + +if [ -n "${CONFIG_IMAGE}" ]; then + set -- -drive if=${disk_type},file="${CONFIG_IMAGE}" "$@" +fi + if [ -n "${VM_IMAGE}" ]; then set -- -drive if=${disk_type},file="${SCRIPT_DIR}/${VM_IMAGE}" "$@" fi @@ -104,24 +166,15 @@ if [ -n "${VM_UUID}" ]; then fi if [ -n "${VM_CDROM}" ]; then - set -- -cdrom "$VM_CDROM" "$@" + set -- -cdrom "${SCRIPT_DIR}/${VM_CDROM}" "$@" fi # Default to KVM, fall back on full emulation -# ${METADATA} will be mounted in CoreOS as /media/metadata qemu-system-x86_64 \ -name "$VM_NAME" \ -m ${VM_MEMORY} \ -machine accel=kvm:tcg \ -net nic,vlan=0,model=virtio \ -net user,vlan=0,hostfwd=tcp::"${SSH_PORT}"-:22 \ - -fsdev local,id=metadata,security_model=none,readonly,path="${METADATA}" \ - -device virtio-9p-pci,fsdev=metadata,mount_tag=metadata \ "$@" -RET=$? - - -# Cleanup! -rm -rf "${METADATA}" -trap - EXIT -exit ${RET} +exit $?