Federico Ressi | 71bda86 | 2018-05-28 11:38:56 +0200 | [diff] [blame] | 1 | # This script include functions that allow guest image files customization |
| 2 | # before uploading them to OpenStack image service |
| 3 | |
| 4 | # ensure we don't re-source this in the same environment |
| 5 | [[ -z "$_NEUTRON_TEMPEST_PLUGIN_CUSTOMIZE_IMAGE" ]] || return 0 |
| 6 | declare -r -g _NEUTRON_TEMPEST_PLUGIN_CUSTOMIZE_IMAGE=1 |
| 7 | |
| 8 | source "${NEUTRON_TEMPEST_PLUGIN_DIR}/functions.sh" |
| 9 | |
| 10 | # By default enable guest image customization. It will be automatically skipped |
| 11 | # for cirros images |
| 12 | CUSTOMIZE_IMAGE=${CUSTOMIZE_IMAGE:-True} |
| 13 | |
| 14 | # Image customization is performed using virt-customize |
| 15 | # using direct backend by default |
| 16 | LIBGUESTFS_BACKEND=${LIBGUESTFS_BACKEND:-direct} |
| 17 | |
| 18 | # Disable KVM hardware accelleration by default |
| 19 | LIBGUESTFS_BACKEND_SETTINGS=${LIBGUESTFS_BACKEND_SETTINGS:-force_tcg} |
| 20 | |
| 21 | # Install tools required for customizing guest image files |
| 22 | function install_customize_image_tools { |
| 23 | local do_customize=$(trueorfalse True CUSTOMIZE_IMAGE) |
| 24 | if [ ${do_customize} == True ]; then |
| 25 | # Make sure virt-customize is installed |
| 26 | install_package libguestfs-tools |
| 27 | fi |
| 28 | } |
| 29 | |
| 30 | # Wraps upload_image function to eventually customize image file before |
| 31 | # uploading it via "openstack image create" command |
| 32 | save_function upload_image overridden_upload_image |
| 33 | function upload_image { |
| 34 | local image_url=$1 |
| 35 | |
| 36 | # Fork a subshell to have environment restored at the end of this function |
| 37 | ( |
| 38 | # Check user configuration |
| 39 | local customize_image=$(trueorfalse True CUSTOMIZE_IMAGE) |
| 40 | if [ ${customize_image} == True ]; then |
| 41 | # Temporarly wraps openstack command with openstack_image_create |
| 42 | # function |
| 43 | function openstack { |
| 44 | IMAGE_URL=${image_url} upload_custom_image "$@" |
| 45 | } |
| 46 | fi |
| 47 | |
| 48 | # Execute original upload_image function |
| 49 | overridden_upload_image "$@" |
| 50 | ) |
| 51 | } |
| 52 | |
| 53 | # Wraps "openstack image create" command to customize image file before |
| 54 | # uploading it to OpenstackImage service. |
| 55 | # Called only when ${CUSTOMIZE_IMAGE} is True |
| 56 | function upload_custom_image { |
| 57 | # Copy command arguments for later use |
| 58 | local args=( "$@" ) |
| 59 | |
| 60 | # Look for image create sub-command: |
| 61 | # skip any argument before "image" and "create" words |
| 62 | local i=0 |
| 63 | local subcommands=() |
| 64 | for subcommand in image create; do |
| 65 | for (( ; i < ${#args[@]}; )) { |
| 66 | local arg=${args[i]} |
| 67 | (( ++i )) |
| 68 | if [ "${arg}" == "${subcommand}" ]; then |
| 69 | subcommands+=( "${arg}" ) |
| 70 | break |
| 71 | fi |
| 72 | } |
| 73 | done |
| 74 | |
| 75 | if [ "${subcommands[*]}" == "image create" ]; then |
| 76 | # create image subcommand has been detected |
| 77 | |
| 78 | # Put here temporary files to be delete before exiting from this |
| 79 | # function |
| 80 | local temp_dir=$(mktemp -d) |
| 81 | chmod 777 "${temp_dir}" |
| 82 | |
| 83 | # Parse openstack image create subcommand arguments |
| 84 | local image_url="${IMAGE_URL}" |
| 85 | local image_file= |
| 86 | local disk_format=auto |
| 87 | local container_format=bare |
| 88 | |
| 89 | for (( ; i < ${#args[@]}; )) { |
| 90 | local arg=${args[$i]} |
| 91 | (( ++i )) |
| 92 | |
| 93 | if [[ "${arg}" == --* ]]; then |
| 94 | # Handle --<option_name>=<option_value> syntax |
| 95 | local option_fields=(${arg//=/ }) |
| 96 | local option_name=${option_fields[0]} |
| 97 | local option_value=${option_fields[1]:-} |
| 98 | |
| 99 | case "${option_name}" in |
| 100 | |
| 101 | --container-format) # Found container format |
| 102 | container_format=${option_value:-${args[ (( i++ )) ]}} |
| 103 | ;; |
| 104 | |
| 105 | --disk-format) # Found disk format |
| 106 | disk_format=${option_value:-${args[ (( i++ )) ]}} |
| 107 | ;; |
| 108 | |
| 109 | --file) # Found image file name |
| 110 | image_file=${option_value:-${args[ (( i++ )) ]}} |
| 111 | ;; |
| 112 | esac |
| 113 | fi |
| 114 | } |
| 115 | |
| 116 | if [ "${image_file}" == "" ]; then |
| 117 | # Copy image file from stdin to a temporary file |
| 118 | image_file=${temp_dir}/$(basename "${image_url}") |
| 119 | cat > "${image_file}" |
| 120 | |
| 121 | # Add option to load image from file |
| 122 | args+=( --file "${image_file}" ) |
| 123 | fi |
| 124 | |
| 125 | # Make image file readable and writable by qemu user |
| 126 | sudo chmod 666 "${image_file}" |
| 127 | |
| 128 | # Customize image file |
| 129 | TEMP_DIR=${temp_dir} \ |
| 130 | DISK_FORMAT=${disk_format} \ |
| 131 | customize_image "${image_file}" |
| 132 | fi |
| 133 | |
| 134 | # Upload custom image file |
| 135 | overridden_openstack "${args[@]}" || local error=$? |
| 136 | |
| 137 | # Finally delete temporary files |
| 138 | sudo rm -fR "${temp_dir}" || true |
| 139 | |
| 140 | return ${error:-0} |
| 141 | } |
| 142 | |
| 143 | function overridden_openstack { |
| 144 | "$(which openstack)" "$@" |
| 145 | } |
| 146 | |
| 147 | # Execute customization commands on a VM with attached guest image file. |
| 148 | # Called only when ${CUSTOMIZE_IMAGE} is True |
| 149 | function customize_image { |
| 150 | local image_file=$1 |
| 151 | local top_dir=$(dirname "${NEUTRON_TEMPEST_PLUGIN_DIR}") |
| 152 | ( |
| 153 | export TEMP_DIR DISK_FORMAT RC_DIR |
| 154 | if [[ "$(basename ${image_file})" == ubuntu-* ]]; then |
| 155 | "${top_dir}/tools/customize_ubuntu_image" "${image_file}" |
| 156 | fi |
| 157 | ) |
| 158 | } |