Add image setup to trove devstack plugin

Main goal is to have a working vm image registered in
trove after devstack installation.

It is a first step towards trovestack-redesign as described
in https://etherpad.openstack.org/p/trovestack-redesign

It is enabled by default during devstack installation with
trove enabled plugin, but it can be skipped by setting
DISABLE_TROVE_IMAGE_SETUP=TRUE

Implementation details:
* export environmental variables for diskimage-builder
* build an image with disk-image-create script
* register the newly created image in trove
* add tripleo-elements information to default settings

Change-Id: I6e57890c5b6fb65e9b8c63363f92e5a7c70e523e
Signed-off-by: Dariusz Krol <d.krol@samsung.com>
This commit is contained in:
Dariusz Krol 2018-10-01 15:57:26 +02:00
parent c63c5888c2
commit 68a4819dd4
6 changed files with 152 additions and 20 deletions

View File

@ -291,6 +291,9 @@ function configure_trove {
# install_trove() - Collect source and prepare
function install_trove {
echo "Changing stack user sudoers"
echo "stack ALL=(ALL) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/60_stack_sh_allow_all
setup_develop $TROVE_DIR
if [[ "${TROVE_USE_MOD_WSGI}" == "TRUE" ]]; then
@ -353,6 +356,12 @@ function init_trove {
--os-password ${ADMIN_PASSWORD} \
--os-project-name ${ALT_TENANT_NAME}
# build and upload sample Trove mysql instance if not set otherwise
if [[ ${TROVE_DISABLE_IMAGE_SETUP} != "TRUE" ]]; then
echo "Setup datastore image"
_setup_minimal_image
fi
# If no guest image is specified, skip remaining setup
[ -z "$TROVE_GUEST_IMAGE_URL" ] && return 0
@ -559,6 +568,120 @@ function configure_tempest_for_trove {
fi
}
# _setup_minimal_image() - build and register in Trove a vm image with mysql
# - datastore can be set via env variables
function _setup_minimal_image {
##### Prerequisites:
##### - SSH KEYS has to be created on controller
##### - trove will access controller ip to get trove source code by using HOST_SCP_USERNAME and an ssh key
##### - we assume tripleo elements and all other elements have been downloaded
echo "Exporting image-related environmental variables"
PRIMARY_IP=$(ip route get 8.8.8.8 | head -1 | cut -d' ' -f8)
export CONTROLLER_IP=${CONTROLLER_IP:-$PRIMARY_IP}
export HOST_USERNAME=${HOST_USERNAME:-'stack'}
export HOST_SCP_USERNAME=${HOST_SCP_USERNAME:-'stack'}
export GUEST_USERNAME=${GUEST_USERNAME:-'ubuntu'}
export PATH_TROVE=${PATH_TROVE:-'/opt/stack/trove'}
export ESCAPED_PATH_TROVE=$(echo $PATH_TROVE | sed 's/\//\\\//g')
export TROVESTACK_SCRIPTS=${TROVESTACK_SCRIPTS:-'/opt/stack/trove/integration/scripts'}
export SERVICE_TYPE=${SERVICE_TYPE:-'mysql'}
export SSH_DIR=${SSH_DIR:-'/opt/stack/.ssh'}
export GUEST_LOGDIR=${GUEST_LOGDIR:-'/var/log/trove/'}
export ESCAPED_GUEST_LOGDIR=$(echo $GUEST_LOGDIR | sed 's/\//\\\//g')
export DIB_CLOUD_INIT_DATASOURCES="ConfigDrive"
export DISTRO="ubuntu"
export VM=${VM:-'/opt/stack/images/ubuntu_mysql/ubuntu_mysql'}
if [ -d "$TROVESTACK_SCRIPTS/files/elements" ]; then
export ELEMENTS_PATH=$TROVESTACK_SCRIPTS/files/elements
else
export ELEMENTS_PATH=.
fi
if [ ! -z "$PATH_DISKIMAGEBUILDER" ]; then
export ELEMENTS_PATH+=:$PATH_DISKIMAGEBUILDER/elements
elif [ -d "/usr/local/lib/python2.7/dist-packages/diskimage_builder" ]; then
PATH_DISKIMG="/usr/local/lib/python2.7/dist-packages/diskimage_builder"
export ELEMENTS_PATH+=:$PATH_DISKIMG/elements
fi
if [ ! -z "$PATH_TRIPLEO_ELEMENTS" ]; then
export ELEMENTS_PATH+=:$PATH_TRIPLEO_ELEMENTS/elements
else
git_clone $TRIPLEO_IMAGES_REPO $TRIPLEO_IMAGES_DIR $TRIPLEO_IMAGES_BRANCH
setup_develop $TRIPLEO_IMAGES_DIR
export ELEMENTS_PATH+=:$TRIPLEO_IMAGES_DIR/elements
fi
export DIB_APT_CONF_DIR=/etc/apt/apt.conf.d
export DIB_CLOUD_INIT_ETC_HOSTS=true
export QEMU_IMG_OPTIONS="--qemu-img-options compat=1.1"
export RELEASE=${RELEASE:-'xenial'}
export DIB_RELEASE=${RELEASE:-'xenial'}
export TROVE_GUESTAGENT_CONF=${TROVE_GUESTAGENT_CONF:-'/etc/trove/trove-guestagent.conf'}
mkdir -p ${SSH_DIR}
/usr/bin/ssh-keygen -f ${SSH_DIR}/id_rsa -q -N ""
cat ${SSH_DIR}/id_rsa.pub >> ${SSH_DIR}/authorized_keys
chmod 600 ${SSH_DIR}/authorized_keys
echo "Run disk image create to actually create a new image"
disk-image-create -a amd64 -o "${VM}" -x ${QEMU_IMG_OPTIONS} ${DISTRO} \
vm cloud-init-datasources ${DISTRO}-guest ${DISTRO}-${RELEASE}-guest \
${DISTRO}-${SERVICE_TYPE} ${DISTRO}-${RELEASE}-${SERVICE_TYPE}
QCOW_IMAGE="$VM.qcow2"
if [ ! -f $QCOW_IMAGE ]; then
echo "Image file was not found at $QCOW_IMAGE. Probably it was not created."
return 1
fi
DATASTORE=$SERVICE_TYPE
DATASTORE_VERSION=${DATASTORE_VERSION:-'5.7'}
ACTIVE=1
INACTIVE=0
echo "Add image to glance"
GLANCE_OUT=$(openstack --os-url $GLANCE_SERVICE_PROTOCOL://$GLANCE_HOSTPORT \
image create $DISTRO-${DATASTORE}-${DATASTORE_VERSION} \
--public --disk-format qcow2 --container-format bare --file $QCOW_IMAGE)
glance_image_id=$(echo "$GLANCE_OUT" | grep '| id ' | awk '{print $4}')
echo "Create datastore specific entry in Trove AFAIK one per datastore, do not need when changing image"
$TROVE_MANAGE datastore_update $DATASTORE ""
echo "Connect datastore entry to glance image"
$TROVE_MANAGE datastore_version_update $DATASTORE $DATASTORE_VERSION $DATASTORE $glance_image_id "" $ACTIVE
echo "Set default datastore version"
$TROVE_MANAGE datastore_update $DATASTORE $DATASTORE_VERSION
# just for tests
$TROVE_MANAGE datastore_version_update "$DATASTORE" "inactive_version" "manager1" $glance_image_id "" $INACTIVE
$TROVE_MANAGE datastore_update Test_Datastore_1 ""
echo "Add validation rules if available"
if [ -f "$PATH_TROVE"/trove/templates/$DATASTORE/validation-rules.json ]; then
$TROVE_MANAGE db_load_datastore_config_parameters "$DATASTORE" "$DATASTORE_VERSION" \
"$PATH_TROVE"/trove/templates/$DATASTORE/validation-rules.json
fi
echo "Generate cloudinit"
CLOUDINIT_PATH=/etc/trove/cloudinit/mysql.cloudinit
if [ ! -f $CLOUDINIT_PATH ]; then
sudo mkdir -p $(dirname $CLOUDINIT_PATH)
sudo echo "#!/usr/bin/env bash" | sudo tee $CLOUDINIT_PATH
PUBKEY=`cat ${SSH_DIR}/id_rsa.pub`
sudo echo "echo '${PUBKEY}' > /home/${GUEST_USERNAME}/.ssh/authorized_keys" | sudo tee --append $CLOUDINIT_PATH
fi
}
# Dispatcher for trove plugin
if is_service_enabled trove; then
if [[ "$1" == "stack" && "$2" == "install" ]]; then

View File

@ -14,6 +14,10 @@ TROVE_DASHBOARD_DIR=${TROVE_DASHBOARD_DIR:-${DEST}/trove-dashboard}
TROVE_DASHBOARD_REPO=${TROVE_DASHBOARD_REPO:-${GIT_BASE}/openstack/trove-dashboard.git}
TROVE_DASHBOARD_BRANCH=${TROVE_DASHBOARD_BRANCH:-master}
TRIPLEO_IMAGES_DIR=${TRIPLEO_IMAGES_DIR:-${DEST}/tripleo-image-elements}
TRIPLEO_IMAGES_REPO=${TRIPLEO_IMAGES_REPO:-${GIT_BASE}/openstack/tripleo-image-elements.git}
TRIPLEO_IMAGES_BRANCH=${TRIPLEO_IMAGES_BRANCH:-master}
# Set up configuration directory and files
TROVE_CONF_DIR=${TROVE_CONF_DIR:-/etc/trove}
TROVE_CONF=${TROVE_CONF:-${TROVE_CONF_DIR}/trove.conf}

View File

@ -852,26 +852,21 @@ function cmd_build_and_upload_image() {
exit 1
fi
local IMAGE_URL=""
# Use /tmp as file_cache
FILES=/tmp
if [[ -n $IMAGE_DOWNLOAD_URL ]]; then
exclaim "Downloading and using cached image"
IMAGE_URL=$IMAGE_DOWNLOAD_URL
else
exclaim "Trying to build image"
GLANCE_IMAGEID=$(openstack $CLOUD_ADMIN_ARG image list | grep "$DATASTORE_TYPE" | get_field 1)
echo "IMAGEID: $GLANCE_IMAGEID"
if [[ -z $GLANCE_IMAGEID ]]; then
build_guest_image "${DATASTORE_TYPE}"
QCOW_IMAGE=`find $VM_PATH -name '*.qcow2'`
IMAGE_URL="file://$QCOW_IMAGE"
fi
GLANCE_IMAGEID=`get_glance_id upload_image $IMAGE_URL`
[[ -z "$GLANCE_IMAGEID" ]] && echo "Glance upload failed!" && exit 1
echo "IMAGE ID: $GLANCE_IMAGEID"
GLANCE_IMAGEIDS=$(openstack $CLOUD_ADMIN_ARG image list | grep $(basename $IMAGE_URL .qcow2) | get_field 1)
if [[ -n $GLANCE_IMAGEIDS ]]; then
openstack $CLOUD_ADMIN_ARG image delete $GLANCE_IMAGEIDS
if [[ -f /etc/trove/cloudinit/mysql.cloudinit ]]; then
sudo cp /etc/trove/cloudinit/mysql.cloudinit /etc/trove/cloudinit/${DATASTORE_TYPE}.cloudinit
fi
fi
GLANCE_IMAGEID=`get_glance_id upload_image $IMAGE_URL`
[[ -z "$GLANCE_IMAGEID" ]] && echo "Glance upload failed!" && exit 1
echo "IMAGE ID: $GLANCE_IMAGEID"
exclaim "Updating Datastores"
cmd_set_datastore "${GLANCE_IMAGEID}" "${DATASTORE_TYPE}" "${RESTART_TROVE}"
@ -1341,7 +1336,17 @@ function cmd_gate_tests() {
TROVESTACK_DUMP_ENV=true
# Devstack vm-gate runs as a non-ubuntu user, but needs to connect to the guest image as ubuntu
echo "User=ubuntu" >> $HOME/.ssh/config
export TROVE_TEST_SSH_USER='ubuntu'
export TROVE_TEST_SSH_KEY_FILE=$HOME/.ssh/id_rsa
CLOUDINIT_PATH=/etc/trove/cloudinit/mysql.cloudinit
PUBKEY=`cat ${HOME}/.ssh/id_rsa.pub`
sudo echo "#!/bin/sh" | sudo tee $CLOUDINIT_PATH
sudo echo "" | sudo tee -a $CLOUDINIT_PATH
sudo echo "echo '${PUBKEY}' > /home/ubuntu/.ssh/authorized_keys" | sudo tee -a $CLOUDINIT_PATH
sudo echo "chmod 700 /home/ubuntu/.ssh" | sudo tee -a $CLOUDINIT_PATH
sudo echo "chmod 600 /home/ubuntu/.ssh/authorized_keys" | sudo tee -a $CLOUDINIT_PATH
# Fix iptables rules that prevent amqp connections from the devstack box to the guests
sudo iptables -D openstack-INPUT -j REJECT --reject-with icmp-host-prohibited || true

View File

@ -102,6 +102,6 @@ SWIFT_DISK_IMAGE=${SWIFT_DATA_DIR}/drives/images/swift.img
#export TROVE_MAX_VOLUMES_PER_TENANT=40
#export TROVE_AGENT_CALL_LOW_TIMEOUT=15
#export TROVE_AGENT_CALL_HIGH_TIMEOUT=300
#export TROVE_RESIZE_TIME_OUT=900
#export TROVE_RESIZE_TIME_OUT=3600
#export TROVE_USAGE_TIMEOUT=1500
#export TROVE_STATE_CHANGE_WAIT_TIME=180

View File

@ -934,7 +934,7 @@ class BaseMySqlApp(object):
LOG.info("Starting slave replication.")
with self.local_sql_client(self.get_engine()) as client:
client.execute('START SLAVE')
self._wait_for_slave_status("ON", client, 60)
self._wait_for_slave_status("ON", client, 180)
def stop_slave(self, for_failover):
replication_user = None
@ -944,7 +944,7 @@ class BaseMySqlApp(object):
replication_user = result.first()['Master_User']
client.execute('STOP SLAVE')
client.execute('RESET SLAVE ALL')
self._wait_for_slave_status("OFF", client, 30)
self._wait_for_slave_status("OFF", client, 180)
if not for_failover:
client.execute('DROP USER ' + replication_user)
return {

View File

@ -177,7 +177,7 @@ class VerifySlave(object):
return find_database
@test
@time_out(5 * 60)
@time_out(20 * 60)
def test_correctly_started_replication(self):
poll_until(slave_is_running())