Improve guest image creation in devstack
Change-Id: I0ef8cbc4babc5c6b9f2936923ffe2837ecc3da74
This commit is contained in:
parent
6c50dec163
commit
3c09e6178a
@ -75,9 +75,8 @@ function create_trove_accounts {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# _cleanup_trove_apache_wsgi - Removes all the WSGI related files and
|
# Removes all the WSGI related files and restart apache.
|
||||||
# restart apache.
|
function cleanup_trove_apache_wsgi {
|
||||||
function _cleanup_trove_apache_wsgi {
|
|
||||||
sudo rm -rf $TROVE_WSGI_DIR
|
sudo rm -rf $TROVE_WSGI_DIR
|
||||||
sudo rm -f $(apache_site_config_for trove-api)
|
sudo rm -f $(apache_site_config_for trove-api)
|
||||||
restart_apache_server
|
restart_apache_server
|
||||||
@ -98,7 +97,7 @@ function cleanup_trove {
|
|||||||
|
|
||||||
if [[ "${TROVE_USE_MOD_WSGI}" == "TRUE" ]]; then
|
if [[ "${TROVE_USE_MOD_WSGI}" == "TRUE" ]]; then
|
||||||
echo "Cleaning up Trove's WSGI setup"
|
echo "Cleaning up Trove's WSGI setup"
|
||||||
_cleanup_trove_apache_wsgi
|
cleanup_trove_apache_wsgi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,9 +164,8 @@ function configure_nova_kvm {
|
|||||||
echo "configure_nova_kvm: using virt_type: ${virt_type} for cpu: ${cpu}."
|
echo "configure_nova_kvm: using virt_type: ${virt_type} for cpu: ${cpu}."
|
||||||
}
|
}
|
||||||
|
|
||||||
# _config_trove_apache_wsgi() - Setup WSGI config files for Trove and
|
# Setup WSGI config files for Trove and enable the site
|
||||||
# enable the site
|
function config_trove_apache_wsgi {
|
||||||
function _config_trove_apache_wsgi {
|
|
||||||
local trove_apache_conf
|
local trove_apache_conf
|
||||||
|
|
||||||
sudo mkdir -p ${TROVE_WSGI_DIR}
|
sudo mkdir -p ${TROVE_WSGI_DIR}
|
||||||
@ -258,7 +256,7 @@ function configure_trove {
|
|||||||
# configure apache related files
|
# configure apache related files
|
||||||
if [[ "${TROVE_USE_MOD_WSGI}" == "TRUE" ]]; then
|
if [[ "${TROVE_USE_MOD_WSGI}" == "TRUE" ]]; then
|
||||||
echo "Configuring Trove to use mod-wsgi and Apache"
|
echo "Configuring Trove to use mod-wsgi and Apache"
|
||||||
_config_trove_apache_wsgi
|
config_trove_apache_wsgi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Use these values only if they're set
|
# Use these values only if they're set
|
||||||
@ -317,54 +315,12 @@ function install_python_troveclient {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# init_trove() - Initializes Trove Database as a Service
|
function init_trove_db {
|
||||||
function init_trove {
|
|
||||||
# (Re)Create trove db
|
# (Re)Create trove db
|
||||||
recreate_database trove
|
recreate_database trove
|
||||||
|
|
||||||
# Initialize the trove database
|
# Initialize the trove database
|
||||||
$TROVE_MANAGE db_sync
|
$TROVE_MANAGE db_sync
|
||||||
|
|
||||||
# build and upload sample Trove mysql instance if not set otherwise.
|
|
||||||
# We recommend to use trovestack tooling for image build.
|
|
||||||
TROVE_DISABLE_IMAGE_SETUP=`echo ${TROVE_DISABLE_IMAGE_SETUP,,}`
|
|
||||||
if [[ ${TROVE_DISABLE_IMAGE_SETUP} != "true" ]]; then
|
|
||||||
echo "Setup datastore image."
|
|
||||||
_setup_minimal_image
|
|
||||||
else
|
|
||||||
echo "Skip datastore image building."
|
|
||||||
fi
|
|
||||||
[ -z "$TROVE_GUEST_IMAGE_URL" ] && return 0
|
|
||||||
|
|
||||||
# Find the glance id for the trove guest image
|
|
||||||
# The image is uploaded by stack.sh -- see $IMAGE_URLS handling
|
|
||||||
GUEST_IMAGE_NAME=$(basename "$TROVE_GUEST_IMAGE_URL")
|
|
||||||
GUEST_IMAGE_NAME=${GUEST_IMAGE_NAME%.*}
|
|
||||||
|
|
||||||
TOKEN=$(openstack token issue -c id -f value)
|
|
||||||
TROVE_GUEST_IMAGE_ID=$(openstack --os-token $TOKEN --os-url $GLANCE_SERVICE_PROTOCOL://$GLANCE_HOSTPORT image list | grep "${GUEST_IMAGE_NAME}" | get_field 1)
|
|
||||||
if [ -z "$TROVE_GUEST_IMAGE_ID" ]; then
|
|
||||||
# If no glance id is found, skip remaining setup
|
|
||||||
echo "Datastore ${TROVE_DATASTORE_TYPE} will not be created: guest image ${GUEST_IMAGE_NAME} not found."
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Now that we have the guest image id, initialize appropriate datastores / datastore versions
|
|
||||||
$TROVE_MANAGE datastore_update "$TROVE_DATASTORE_TYPE" ""
|
|
||||||
$TROVE_MANAGE datastore_version_update "$TROVE_DATASTORE_TYPE" "$TROVE_DATASTORE_VERSION" "$TROVE_DATASTORE_TYPE" \
|
|
||||||
"$TROVE_GUEST_IMAGE_ID" "$TROVE_DATASTORE_PACKAGE" 1
|
|
||||||
$TROVE_MANAGE datastore_version_update "$TROVE_DATASTORE_TYPE" "inactive_version" "inactive_manager" "$TROVE_GUEST_IMAGE_ID" "" 0
|
|
||||||
$TROVE_MANAGE datastore_update "$TROVE_DATASTORE_TYPE" "$TROVE_DATASTORE_VERSION"
|
|
||||||
$TROVE_MANAGE datastore_update "Inactive_Datastore" ""
|
|
||||||
|
|
||||||
# Some datastores provide validation rules.
|
|
||||||
# if one is provided, configure it.
|
|
||||||
if [ -f "${TROVE_DIR}/trove/templates/${TROVE_DATASTORE_TYPE}"/validation-rules.json ]; then
|
|
||||||
echo "Configuring validation rules for ${TROVE_DATASTORE_TYPE}"
|
|
||||||
$TROVE_MANAGE db_load_datastore_config_parameters \
|
|
||||||
"$TROVE_DATASTORE_TYPE" "$TROVE_DATASTORE_VERSION" \
|
|
||||||
"${TROVE_DIR}/trove/templates/${TROVE_DATASTORE_TYPE}"/validation-rules.json
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function create_mgmt_subnet_v4 {
|
function create_mgmt_subnet_v4 {
|
||||||
@ -380,7 +336,7 @@ function create_mgmt_subnet_v4 {
|
|||||||
|
|
||||||
# Create private IPv6 subnet
|
# Create private IPv6 subnet
|
||||||
# Note: Trove is not fully tested in IPv6.
|
# Note: Trove is not fully tested in IPv6.
|
||||||
function _create_subnet_v6 {
|
function create_subnet_v6 {
|
||||||
local project_id=$1
|
local project_id=$1
|
||||||
local net_id=$2
|
local net_id=$2
|
||||||
local name=$3
|
local name=$3
|
||||||
@ -426,13 +382,13 @@ function setup_mgmt_network() {
|
|||||||
fi
|
fi
|
||||||
# Trove doesn't support IPv6 for now.
|
# Trove doesn't support IPv6 for now.
|
||||||
# if [[ "$IP_VERSION" =~ .*6 ]]; then
|
# if [[ "$IP_VERSION" =~ .*6 ]]; then
|
||||||
# NEW_IPV6_SUBNET_ID=$(_create_subnet_v6 ${PROJECT_ID} ${network_id} ${IPV6_SUBNET_NAME})
|
# NEW_IPV6_SUBNET_ID=$(create_subnet_v6 ${PROJECT_ID} ${network_id} ${IPV6_SUBNET_NAME})
|
||||||
# openstack router add subnet $ROUTER_ID $NEW_IPV6_SUBNET_ID
|
# openstack router add subnet $ROUTER_ID $NEW_IPV6_SUBNET_ID
|
||||||
# fi
|
# fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Set up Trove management network and make configuration change.
|
# Set up Trove management network and make configuration change.
|
||||||
function finalize_trove_network {
|
function config_trove_network {
|
||||||
echo "Finalizing Neutron networking for Trove"
|
echo "Finalizing Neutron networking for Trove"
|
||||||
echo "Dumping current network parameters:"
|
echo "Dumping current network parameters:"
|
||||||
echo " SERVICE_HOST: $SERVICE_HOST"
|
echo " SERVICE_HOST: $SERVICE_HOST"
|
||||||
@ -531,117 +487,38 @@ function configure_tempest_for_trove {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# _setup_minimal_image() - build and register in Trove a vm image with mysql
|
# Use trovestack to create guest image and register the image in the datastore.
|
||||||
# - datastore can be set via env variables
|
function create_guest_image {
|
||||||
# (lxkong): This function is deprecated in favor of trovestack script.
|
TROVE_DISABLE_IMAGE_SETUP=`echo ${TROVE_DISABLE_IMAGE_SETUP,,}`
|
||||||
function _setup_minimal_image {
|
if [[ ${TROVE_DISABLE_IMAGE_SETUP} == "true" ]]; then
|
||||||
##### Prerequisites:
|
echo "Skip creating guest image."
|
||||||
##### - SSH KEYS has to be created on controller
|
return 0
|
||||||
##### - 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 | awk '{print $7}')
|
|
||||||
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 TROVE_DATASTORE_TYPE=${TROVE_DATASTORE_TYPE:-'mysql'}
|
|
||||||
export TROVE_DATASTORE_VERSION=${TROVE_DATASTORE_VERSION:-'5.7'}
|
|
||||||
export TROVE_DATASTORE_PACKAGE=${TROVE_DATASTORE_PACKAGE:-"${TROVE_DATASTORE_TYPE}-${TROVE_DATASTORE_VERSION}"}
|
|
||||||
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/${DISTRO}_${TROVE_DATASTORE_TYPE}/${DISTRO}_${TROVE_DATASTORE_TYPE}"}
|
|
||||||
|
|
||||||
if [ -d "$TROVESTACK_SCRIPTS/files/elements" ]; then
|
|
||||||
export ELEMENTS_PATH=$TROVESTACK_SCRIPTS/files/elements
|
|
||||||
else
|
|
||||||
export ELEMENTS_PATH=.
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -z "$PATH_DISKIMAGEBUILDER" ]; then
|
echo "Starting to create guest image..."
|
||||||
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
|
$DEST/trove/integration/scripts/trovestack build-image ${TROVE_DATASTORE_TYPE} ${TROVE_IMAGE_OS} ${TROVE_IMAGE_OS_RELEASE} true
|
||||||
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
|
image_name=${TROVE_IMAGE_OS}-${TROVE_DATASTORE_TYPE}
|
||||||
fi
|
image_file=$HOME/images/${image_name}.qcow2
|
||||||
|
if [ ! -f ${image_file} ]; then
|
||||||
export QEMU_IMG_OPTIONS="--qemu-img-options compat=1.1"
|
echo "Image file was not found at ${image_file}. Probably it was not created."
|
||||||
export RELEASE=${RELEASE:-'xenial'}
|
|
||||||
export DIB_APT_CONF_DIR=/etc/apt/apt.conf.d
|
|
||||||
export DIB_CLOUD_INIT_ETC_HOSTS=true
|
|
||||||
export DIB_RELEASE=${RELEASE:-'xenial'}
|
|
||||||
|
|
||||||
# https://cloud-images.ubuntu.com/releases is more stable than the daily
|
|
||||||
# builds(https://cloud-images.ubuntu.com/xenial/current/),
|
|
||||||
# e.g. sometimes SHA256SUMS file is missing in the daily builds
|
|
||||||
declare -A releasemapping=( ["xenial"]="16.04" ["bionic"]="18.04")
|
|
||||||
export DIB_CLOUD_IMAGES="https://cloud-images.ubuntu.com/releases/${DIB_RELEASE}/release/"
|
|
||||||
export BASE_IMAGE_FILE="ubuntu-${releasemapping[${DIB_RELEASE}]}-server-cloudimg-amd64-root.tar.gz"
|
|
||||||
|
|
||||||
export TROVE_GUESTAGENT_CONF=${TROVE_GUESTAGENT_CONF:-'/etc/trove/trove-guestagent.conf'}
|
|
||||||
|
|
||||||
if [[ -d ${SSH_DIR} && -f ${SSH_DIR}/id_rsa.pub ]]; then
|
|
||||||
cat ${SSH_DIR}/id_rsa.pub >> ${SSH_DIR}/authorized_keys
|
|
||||||
sort ${SSH_DIR}/authorized_keys | uniq > ${SSH_DIR}/authorized_keys.uniq
|
|
||||||
mv ${SSH_DIR}/authorized_keys.uniq ${SSH_DIR}/authorized_keys
|
|
||||||
else
|
|
||||||
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
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Make sure the guest agent has permission to ssh into the devstack host
|
|
||||||
# in order to download trove code during the service initialization.
|
|
||||||
home_keys=$HOME/.ssh/authorized_keys
|
|
||||||
cat ${SSH_DIR}/id_rsa.pub >> ${home_keys}
|
|
||||||
sort ${home_keys} | uniq > ${home_keys}.uniq
|
|
||||||
mv ${home_keys}.uniq ${home_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}-${TROVE_DATASTORE_TYPE} ${DISTRO}-${RELEASE}-${TROVE_DATASTORE_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
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
ACTIVE=1
|
ACTIVE=1
|
||||||
INACTIVE=0
|
INACTIVE=0
|
||||||
|
|
||||||
echo "Add image to glance"
|
echo "Add the image to glance"
|
||||||
GLANCE_OUT=$(openstack --os-url $GLANCE_SERVICE_PROTOCOL://$GLANCE_HOSTPORT \
|
glance_image_id=$(openstack --os-region-name RegionOne --os-password ${SERVICE_PASSWORD} \
|
||||||
image create $DISTRO-${TROVE_DATASTORE_TYPE}-${TROVE_DATASTORE_VERSION} \
|
--os-project-name service --os-username trove \
|
||||||
--public --disk-format qcow2 --container-format bare --file $QCOW_IMAGE)
|
image create ${TROVE_IMAGE_OS}-${TROVE_IMAGE_OS_RELEASE}-${TROVE_DATASTORE_TYPE} \
|
||||||
glance_image_id=$(echo "$GLANCE_OUT" | grep '| id ' | awk '{print $4}')
|
--disk-format qcow2 --container-format bare --property hw_rng_model='virtio' --file ${image_file} \
|
||||||
|
-c id -f value)
|
||||||
|
|
||||||
echo "Create datastore specific entry in Trove AFAIK one per datastore, do not need when changing image"
|
echo "Register the image in datastore"
|
||||||
$TROVE_MANAGE datastore_update $TROVE_DATASTORE_TYPE ""
|
$TROVE_MANAGE datastore_update $TROVE_DATASTORE_TYPE ""
|
||||||
|
|
||||||
echo "Connect datastore entry to glance image"
|
|
||||||
$TROVE_MANAGE datastore_version_update $TROVE_DATASTORE_TYPE $TROVE_DATASTORE_VERSION $TROVE_DATASTORE_TYPE $glance_image_id "" $ACTIVE
|
$TROVE_MANAGE datastore_version_update $TROVE_DATASTORE_TYPE $TROVE_DATASTORE_VERSION $TROVE_DATASTORE_TYPE $glance_image_id "" $ACTIVE
|
||||||
|
|
||||||
echo "Set default datastore version"
|
|
||||||
$TROVE_MANAGE datastore_update $TROVE_DATASTORE_TYPE $TROVE_DATASTORE_VERSION
|
$TROVE_MANAGE datastore_update $TROVE_DATASTORE_TYPE $TROVE_DATASTORE_VERSION
|
||||||
|
|
||||||
# just for tests
|
# just for tests
|
||||||
@ -649,24 +526,22 @@ function _setup_minimal_image {
|
|||||||
$TROVE_MANAGE datastore_update Test_Datastore_1 ""
|
$TROVE_MANAGE datastore_update Test_Datastore_1 ""
|
||||||
|
|
||||||
echo "Add validation rules if available"
|
echo "Add validation rules if available"
|
||||||
if [ -f "$PATH_TROVE"/trove/templates/$TROVE_DATASTORE_TYPE/validation-rules.json ]; then
|
if [ -f $DEST/trove/trove/templates/$TROVE_DATASTORE_TYPE/validation-rules.json ]; then
|
||||||
$TROVE_MANAGE db_load_datastore_config_parameters "$TROVE_DATASTORE_TYPE" "$TROVE_DATASTORE_VERSION" \
|
$TROVE_MANAGE db_load_datastore_config_parameters "$TROVE_DATASTORE_TYPE" "$TROVE_DATASTORE_VERSION" \
|
||||||
"$PATH_TROVE"/trove/templates/$TROVE_DATASTORE_TYPE/validation-rules.json
|
$DEST/trove/trove/templates/$TROVE_DATASTORE_TYPE/validation-rules.json
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Generate cloudinit"
|
# To avoid 'Connection timed out' error of sudo command inside the guest agent.
|
||||||
CLOUDINIT_PATH=/etc/trove/cloudinit/mysql.cloudinit
|
CLOUDINIT_PATH=/etc/trove/cloudinit/${TROVE_DATASTORE_TYPE}.cloudinit
|
||||||
|
sudo mkdir -p $(dirname "$CLOUDINIT_PATH")
|
||||||
if [ ! -f $CLOUDINIT_PATH ]; then
|
sudo touch "$CLOUDINIT_PATH"
|
||||||
sudo mkdir -p $(dirname $CLOUDINIT_PATH)
|
sudo tee $CLOUDINIT_PATH >/dev/null <<'EOF'
|
||||||
|
#cloud-config
|
||||||
sudo echo "#!/usr/bin/env bash" | sudo tee $CLOUDINIT_PATH
|
manage_etc_hosts: "localhost"
|
||||||
PUBKEY=`cat ${SSH_DIR}/id_rsa.pub`
|
EOF
|
||||||
sudo echo "echo '${PUBKEY}' > /home/${GUEST_USERNAME}/.ssh/authorized_keys" | sudo tee --append $CLOUDINIT_PATH
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function _config_nova_keypair {
|
function config_nova_keypair {
|
||||||
export SSH_DIR=${SSH_DIR:-"$HOME/.ssh"}
|
export SSH_DIR=${SSH_DIR:-"$HOME/.ssh"}
|
||||||
|
|
||||||
if [[ ! -f ${SSH_DIR}/id_rsa.pub ]]; then
|
if [[ ! -f ${SSH_DIR}/id_rsa.pub ]]; then
|
||||||
@ -689,7 +564,14 @@ function _config_nova_keypair {
|
|||||||
iniset $TROVE_CONF DEFAULT nova_keypair ${TROVE_MGMT_KEYPAIR_NAME}
|
iniset $TROVE_CONF DEFAULT nova_keypair ${TROVE_MGMT_KEYPAIR_NAME}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _config_mgmt_security_group {
|
function config_cinder_volume_type {
|
||||||
|
volume_type=$(openstack --os-region-name RegionOne --os-password ${SERVICE_PASSWORD} \
|
||||||
|
--os-project-name service --os-username trove \
|
||||||
|
volume type list -c Name -f value | awk 'NR==1 {print}')
|
||||||
|
|
||||||
|
iniset $TROVE_CONF DEFAULT cinder_volume_type ${volume_type}
|
||||||
|
}
|
||||||
|
function config_mgmt_security_group {
|
||||||
local sgid
|
local sgid
|
||||||
|
|
||||||
echo "Creating Trove management security group."
|
echo "Creating Trove management security group."
|
||||||
@ -719,17 +601,13 @@ if is_service_enabled trove; then
|
|||||||
echo_summary "Configuring Trove"
|
echo_summary "Configuring Trove"
|
||||||
configure_trove
|
configure_trove
|
||||||
elif [[ "$1" == "stack" && "$2" == "extra" ]]; then
|
elif [[ "$1" == "stack" && "$2" == "extra" ]]; then
|
||||||
# Initialize trove
|
init_trove_db
|
||||||
init_trove
|
config_nova_keypair
|
||||||
|
config_cinder_volume_type
|
||||||
|
config_mgmt_security_group
|
||||||
|
config_trove_network
|
||||||
|
create_guest_image
|
||||||
|
|
||||||
_config_nova_keypair
|
|
||||||
_config_mgmt_security_group
|
|
||||||
|
|
||||||
# finish the last step in trove network configuration
|
|
||||||
echo_summary "Finalizing Trove Network Configuration"
|
|
||||||
finalize_trove_network
|
|
||||||
|
|
||||||
# Start the trove API and trove taskmgr components
|
|
||||||
echo_summary "Starting Trove"
|
echo_summary "Starting Trove"
|
||||||
start_trove
|
start_trove
|
||||||
|
|
||||||
|
@ -28,6 +28,8 @@ TROVE_LOCAL_CONF_DIR=${TROVE_LOCAL_CONF_DIR:-${TROVE_DIR}/etc/trove}
|
|||||||
TROVE_LOCAL_API_PASTE_INI=${TROVE_LOCAL_API_PASTE_INI:-${TROVE_LOCAL_CONF_DIR}/api-paste.ini}
|
TROVE_LOCAL_API_PASTE_INI=${TROVE_LOCAL_API_PASTE_INI:-${TROVE_LOCAL_CONF_DIR}/api-paste.ini}
|
||||||
TROVE_LOCAL_POLICY_JSON=${TROVE_LOCAL_POLICY_JSON:-${TROVE_LOCAL_CONF_DIR}/policy.json}
|
TROVE_LOCAL_POLICY_JSON=${TROVE_LOCAL_POLICY_JSON:-${TROVE_LOCAL_CONF_DIR}/policy.json}
|
||||||
|
|
||||||
|
TROVE_IMAGE_OS=${TROVE_IMAGE_OS:-"ubuntu"}
|
||||||
|
TROVE_IMAGE_OS_RELEASE=${TROVE_IMAGE_OS_RELEASE:-"xenial"}
|
||||||
TROVE_DATASTORE_TYPE=${TROVE_DATASTORE_TYPE:-"mysql"}
|
TROVE_DATASTORE_TYPE=${TROVE_DATASTORE_TYPE:-"mysql"}
|
||||||
if [[ "$DISTRO" == "xenial" || "$DISTRO" == "bionic" ]]; then
|
if [[ "$DISTRO" == "xenial" || "$DISTRO" == "bionic" ]]; then
|
||||||
TROVE_DATASTORE_VERSION=${TROVE_DATASTORE_VERSION:-"5.7"}
|
TROVE_DATASTORE_VERSION=${TROVE_DATASTORE_VERSION:-"5.7"}
|
||||||
|
@ -2,22 +2,19 @@
|
|||||||
Database service
|
Database service
|
||||||
================
|
================
|
||||||
|
|
||||||
|
The Database service (Trove) provides scalable and reliable Cloud Database as a
|
||||||
|
Service provisioning functionality for both relational and non-relational
|
||||||
|
database engines.
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
|
|
||||||
apache-mod-wsgi.rst
|
apache-mod-wsgi.rst
|
||||||
get_started.rst
|
get_started.rst
|
||||||
install.rst
|
install-devstack.rst
|
||||||
|
install-manual.rst
|
||||||
install-obs.rst
|
install-obs.rst
|
||||||
install-rdo.rst
|
install-rdo.rst
|
||||||
install-ubuntu.rst
|
install-ubuntu.rst
|
||||||
manual_install.rst
|
|
||||||
dashboard.rst
|
dashboard.rst
|
||||||
verify.rst
|
verify.rst
|
||||||
next-steps.rst
|
next-steps.rst
|
||||||
|
|
||||||
|
|
||||||
The Database service (trove) provides cloud provisioning functionality
|
|
||||||
for database engines.
|
|
||||||
|
|
||||||
This chapter assumes a working setup of OpenStack following the
|
|
||||||
`OpenStack Installation Tutorial <http://docs.openstack.org/#install-guides>`_.
|
|
||||||
|
186
doc/source/install/install-devstack.rst
Normal file
186
doc/source/install/install-devstack.rst
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
..
|
||||||
|
Copyright 2019 Catalyst Cloud
|
||||||
|
All Rights Reserved.
|
||||||
|
not use this file except in compliance with the License. You may obtain
|
||||||
|
a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
License for the specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
|
||||||
|
Install Trove in DevStack
|
||||||
|
=========================
|
||||||
|
|
||||||
|
This page describes how to set up a working development
|
||||||
|
environment that can be used in deploying Trove on latest releases
|
||||||
|
of Ubuntu.
|
||||||
|
|
||||||
|
Following these instructions will allow you to have a fully functional Trove
|
||||||
|
environment using the DevStack on Ubuntu 16.04 or 18.04.
|
||||||
|
|
||||||
|
Config DevStack with Trove
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Trove can be enabled in devstack by using the plug-in based interface it
|
||||||
|
offers.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
The following steps have been fully verified both on Ubuntu 16.04 and 18.04.
|
||||||
|
|
||||||
|
Start by cloning the devstack repository using a non-root user(the default user
|
||||||
|
is ``ubuntu``) and change to devstack directory:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
git clone https://opendev.org/openstack/devstack
|
||||||
|
cd devstack/
|
||||||
|
|
||||||
|
Create the ``local.conf`` file with the following minimal devstack
|
||||||
|
configuration, change the ``HOST_IP`` to your own devstack host IP address:
|
||||||
|
|
||||||
|
.. code-block:: ini
|
||||||
|
|
||||||
|
[[local|localrc]]
|
||||||
|
RECLONE=False
|
||||||
|
HOST_IP=<your-host-ip-here>
|
||||||
|
|
||||||
|
enable_plugin trove https:/opendev.org/openstack/trove
|
||||||
|
|
||||||
|
LIBS_FROM_GIT+=,python-troveclient
|
||||||
|
DATABASE_PASSWORD=password
|
||||||
|
ADMIN_PASSWORD=password
|
||||||
|
SERVICE_PASSWORD=password
|
||||||
|
SERVICE_TOKEN=password
|
||||||
|
RABBIT_PASSWORD=password
|
||||||
|
LOGFILE=$DEST/logs/stack.sh.log
|
||||||
|
VERBOSE=True
|
||||||
|
LOG_COLOR=False
|
||||||
|
LOGDAYS=1
|
||||||
|
|
||||||
|
IPV4_ADDRS_SAFE_TO_USE=10.111.0.0/26
|
||||||
|
FIXED_RANGE=10.111.0.0/26
|
||||||
|
NETWORK_GATEWAY=10.111.0.1
|
||||||
|
FLOATING_RANGE=172.30.5.0/24
|
||||||
|
PUBLIC_NETWORK_GATEWAY=172.30.5.1
|
||||||
|
|
||||||
|
# Pre-requisites
|
||||||
|
ENABLED_SERVICES=rabbit,mysql,key
|
||||||
|
|
||||||
|
# Nova
|
||||||
|
enable_service n-api
|
||||||
|
enable_service n-cpu
|
||||||
|
enable_service n-cond
|
||||||
|
enable_service n-sch
|
||||||
|
enable_service n-api-meta
|
||||||
|
enable_service placement-api
|
||||||
|
enable_service placement-client
|
||||||
|
|
||||||
|
# Glance
|
||||||
|
enable_service g-api
|
||||||
|
enable_service g-reg
|
||||||
|
|
||||||
|
# Cinder
|
||||||
|
enable_service cinder
|
||||||
|
enable_service c-api
|
||||||
|
enable_service c-vol
|
||||||
|
enable_service c-sch
|
||||||
|
|
||||||
|
# Neutron
|
||||||
|
enable_service q-svc
|
||||||
|
enable_service q-agt
|
||||||
|
enable_service q-dhcp
|
||||||
|
enable_service q-l3
|
||||||
|
enable_service q-meta
|
||||||
|
|
||||||
|
# enable DVR
|
||||||
|
Q_PLUGIN=ml2
|
||||||
|
Q_ML2_TENANT_NETWORK_TYPE=vxlan
|
||||||
|
Q_DVR_MODE=legacy
|
||||||
|
|
||||||
|
# Swift
|
||||||
|
ENABLED_SERVICES+=,swift
|
||||||
|
SWIFT_HASH=66a3d6b56c1f479c8b4e70ab5c2000f5
|
||||||
|
SWIFT_REPLICAS=1
|
||||||
|
|
||||||
|
# Trove
|
||||||
|
TROVE_DISABLE_IMAGE_SETUP=False
|
||||||
|
|
||||||
|
Take a look at the
|
||||||
|
`options <https://opendev.org/openstack/trove/src/branch/master/devstack/settings>`_
|
||||||
|
you could use to customize the Trove installation.
|
||||||
|
|
||||||
|
Running devstack
|
||||||
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Run the ``stack.sh`` script:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
./stack.sh
|
||||||
|
|
||||||
|
After it completes, you can see there is a MySQL datastore available to create
|
||||||
|
Trove instance:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
$ openstack datastore version list mysql
|
||||||
|
+--------------------------------------+------------------+
|
||||||
|
| ID | Name |
|
||||||
|
+--------------------------------------+------------------+
|
||||||
|
| 9726354d-f989-4a68-9c5f-6e37b1bccc74 | 5.7 |
|
||||||
|
| f81a8448-2f6e-4746-8d97-866ab7dcccee | inactive_version |
|
||||||
|
+--------------------------------------+------------------+
|
||||||
|
|
||||||
|
Create your first Trove instance
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
#. Switch to a non-admin user, choose a Nova flavor ID for the Trove
|
||||||
|
instance.
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
$ source ~/devstack/openrc demo demo
|
||||||
|
$ openstack flavor list
|
||||||
|
+----+---------------+-------+------+-----------+-------+-----------+
|
||||||
|
| ID | Name | RAM | Disk | Ephemeral | VCPUs | Is Public |
|
||||||
|
+----+---------------+-------+------+-----------+-------+-----------+
|
||||||
|
| 1 | m1.tiny | 512 | 1 | 0 | 1 | True |
|
||||||
|
| 2 | m1.small | 2048 | 20 | 0 | 1 | True |
|
||||||
|
| 3 | m1.medium | 4096 | 40 | 0 | 2 | True |
|
||||||
|
| 4 | m1.large | 8192 | 80 | 0 | 4 | True |
|
||||||
|
| 5 | m1.xlarge | 16384 | 160 | 0 | 8 | True |
|
||||||
|
| 6 | mysql-minimum | 512 | 5 | 0 | 1 | True |
|
||||||
|
| c1 | cirros256 | 256 | 1 | 0 | 1 | True |
|
||||||
|
| d1 | ds512M | 512 | 5 | 0 | 1 | True |
|
||||||
|
| d2 | ds1G | 1024 | 10 | 0 | 1 | True |
|
||||||
|
| d3 | ds2G | 2048 | 10 | 0 | 2 | True |
|
||||||
|
| d4 | ds4G | 4096 | 20 | 0 | 4 | True |
|
||||||
|
+----+---------------+-------+------+-----------+-------+-----------+
|
||||||
|
$ flavorid=6
|
||||||
|
|
||||||
|
#. Choose a private network on which the database service can be accessed.
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
$ openstack network list --internal
|
||||||
|
+--------------------------------------+---------+----------------------------------------------------------------------------+
|
||||||
|
| ID | Name | Subnets |
|
||||||
|
+--------------------------------------+---------+----------------------------------------------------------------------------+
|
||||||
|
| a0f3cf12-3562-4064-aa34-61d37265e867 | private | 377e791f-2631-4d8e-93cd-036344b24b3f, 7e04abb4-7c16-4b92-8865-7831ecf3ee66 |
|
||||||
|
+--------------------------------------+---------+----------------------------------------------------------------------------+
|
||||||
|
# netid=a0f3cf12-3562-4064-aa34-61d37265e867
|
||||||
|
|
||||||
|
#. Create the Trove instance.
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
$ openstack database instance create my-first-trove-instance $flavorid \
|
||||||
|
--size 1 \
|
||||||
|
--nic net-id=$netid \
|
||||||
|
--datastore mysql --datastore_version 5.7 \
|
||||||
|
--databases test --users test_user:password
|
243
doc/source/install/install-manual.rst
Normal file
243
doc/source/install/install-manual.rst
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
.. _install-manual:
|
||||||
|
|
||||||
|
Manual Trove Installation
|
||||||
|
=========================
|
||||||
|
|
||||||
|
Objectives
|
||||||
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
This document provides a step-by-step guide for manual installation of Trove
|
||||||
|
with an existing OpenStack environment for development purposes.
|
||||||
|
|
||||||
|
This document will not cover OpenStack setup for other services.
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
A running OpenStack environment installed on Ubuntu 16.04 or 18.04 LTS is
|
||||||
|
required, including the following components:
|
||||||
|
|
||||||
|
- Compute (Nova)
|
||||||
|
- Image Service (Glance)
|
||||||
|
- Identity (Keystone)
|
||||||
|
- Network (Neutron)
|
||||||
|
- If you want to provision databases on block-storage volumes, you also need
|
||||||
|
Block Storage (Cinder)
|
||||||
|
- If you want to do backup/restore or replication, you also need Object Storage
|
||||||
|
(Swift)
|
||||||
|
- AMQP service (RabbitMQ or QPID)
|
||||||
|
- MySQL (SQLite, PostgreSQL) database
|
||||||
|
|
||||||
|
Networking requirements
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
Trove makes use of an "Management Network" that the controller uses to talk to
|
||||||
|
trove instance and vice versa. All the trove instance that Trove deploys will
|
||||||
|
have interfaces and IP addresses on this network. Therefore, it’s important
|
||||||
|
that the subnet deployed on this network be sufficiently large to allow for the
|
||||||
|
maximum number of trove instance and controllers likely to be deployed
|
||||||
|
throughout the lifespan of the cloud installation.
|
||||||
|
|
||||||
|
You must also create a Neutron security group which will be applied to trove
|
||||||
|
instance port created on the management network. The cloud admin has full
|
||||||
|
control of the security group, e.g it can be helpful to allow SSH access to the
|
||||||
|
trove instance from the controller for troubleshooting purposes (ie. TCP port
|
||||||
|
22), though this is not strictly necessary in production environments.
|
||||||
|
|
||||||
|
Finally, you need to add routing or interfaces to this network so that the
|
||||||
|
Trove controller is able to communicate with Nova servers on this network.
|
||||||
|
|
||||||
|
Trove Installation
|
||||||
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Required packages for Trove
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
List of packages to be installed:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
$ sudo apt-get install -y build-essential python-dev libpython-dev \
|
||||||
|
python-setuptools libffi-dev libxslt1-dev libxml2-dev libyaml-dev \
|
||||||
|
libssl-dev zlib1g-dev mysql-client python-pymysql libmysqlclient-dev git
|
||||||
|
|
||||||
|
Python settings
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Install pip:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
curl -SO# https://bootstrap.pypa.io/get-pip.py && sudo python get-pip.py pip==9.0.3 && rm -f get-pip.py
|
||||||
|
|
||||||
|
Install virtualenv, create Trove environment and activate it:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
pip install virtualenv --user
|
||||||
|
virtualenv --system-site-packages trove_env
|
||||||
|
source trove_env/bin/activate
|
||||||
|
|
||||||
|
Get Trove
|
||||||
|
---------
|
||||||
|
|
||||||
|
Obtain the Trove source components from OpenStack repositories:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
cd ~
|
||||||
|
git clone https://opendev.org/openstack/trove.git
|
||||||
|
git clone https://opendev.org/openstack/python-troveclient.git
|
||||||
|
|
||||||
|
|
||||||
|
Install Trove
|
||||||
|
-------------
|
||||||
|
|
||||||
|
First, install the requirements:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
cd ~/trove
|
||||||
|
sudo pip install -r requirements.txt -r test-requirements.txt
|
||||||
|
|
||||||
|
Then, install Trove:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
sudo pip install -e .
|
||||||
|
|
||||||
|
Finally, install the Trove client:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
cd ~/python-troveclient
|
||||||
|
sudo pip install -e .
|
||||||
|
cd ~
|
||||||
|
|
||||||
|
Other required OpenStack clients (python-novaclient, python-keystoneclient,
|
||||||
|
etc.) should already be installed as part of the Trove requirements.
|
||||||
|
|
||||||
|
Prepare Trove for OpenStack
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
You need to run the following commands using OpenStack admin credentials.
|
||||||
|
|
||||||
|
#. Create Trove service user with admin role in the ``service`` project.
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
openstack user create trove --project service --password-prompt
|
||||||
|
openstack role add --user trove --project service admin
|
||||||
|
|
||||||
|
#. Register Trove in Keystone.
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
openstack service create --name trove --description "Database" database
|
||||||
|
openstack endpoint create --region RegionOne database public 'http://<EnvironmentPublicIP>:8779/v1.0/$(tenant_id)s'
|
||||||
|
openstack endpoint create --region RegionOne database admin 'http://<EnvironmentPublicIP>:8779/v1.0/$(tenant_id)s'
|
||||||
|
openstack endpoint create --region RegionOne database internal 'http://<EnvironmentPublicIP>:8779/v1.0/$(tenant_id)s'
|
||||||
|
|
||||||
|
Where <EnvironmentPublicIP> is the IP address of the server where Trove was
|
||||||
|
installed. This IP should be reachable from any hosts that will be used to
|
||||||
|
communicate with Trove.
|
||||||
|
|
||||||
|
Trove configuration
|
||||||
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
There are several configuration files for Trove, you can find samples of the
|
||||||
|
config files in ``etc/trove/`` of Trove repo:
|
||||||
|
|
||||||
|
- api-paste.ini and trove.conf — For trove-api service
|
||||||
|
- trove-guestagent.conf — For trove-guestagent service
|
||||||
|
- ``<datastore_manager>.cloudinit`` — Userdata for VMs during provisioning
|
||||||
|
|
||||||
|
Options in trove.conf
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
#. Config service tenant model, change the values according to your own
|
||||||
|
environment.
|
||||||
|
|
||||||
|
.. code-block:: ini
|
||||||
|
|
||||||
|
nova_proxy_admin_user = admin
|
||||||
|
nova_proxy_admin_pass = password
|
||||||
|
nova_proxy_admin_tenant_name = admin
|
||||||
|
nova_proxy_admin_tenant_id = f472127c03f6410899225e26a3c1d22c
|
||||||
|
nova_proxy_admin_user_domain_name = default
|
||||||
|
nova_proxy_admin_project_domain_name = default
|
||||||
|
remote_nova_client = trove.common.single_tenant_remote.nova_client_trove_admin
|
||||||
|
remote_cinder_client = trove.common.single_tenant_remote.cinder_client_trove_admin
|
||||||
|
remote_neutron_client = trove.common.single_tenant_remote.neutron_client_trove_admin
|
||||||
|
os_region_name = RegionOne
|
||||||
|
|
||||||
|
#. Management config options.
|
||||||
|
|
||||||
|
management_networks
|
||||||
|
Trove management network ID list. Cloud admin needs to create the
|
||||||
|
networks.
|
||||||
|
|
||||||
|
management_security_groups
|
||||||
|
Security group IDs that applied to the management port in the trove
|
||||||
|
instance. Cloud admin needs to create the security groups.
|
||||||
|
|
||||||
|
nova_keypair
|
||||||
|
The Nova keypair used to create trove instance. Cloud admin needs to
|
||||||
|
create the keypair.
|
||||||
|
|
||||||
|
cinder_volume_type
|
||||||
|
The Cinder volume type name used to create volume that attached to the
|
||||||
|
trove instance, otherwise, users need to provide the volume type when
|
||||||
|
creating the instance.
|
||||||
|
|
||||||
|
Prepare Trove database
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Create the Trove database schema:
|
||||||
|
|
||||||
|
- Connect to the storage backend (MySQL, PostgreSQL)
|
||||||
|
- Create a database called `trove` (this database will be used for storing
|
||||||
|
Trove ORM)
|
||||||
|
- Compose connection string. Example:
|
||||||
|
``mysql+pymysql://<user>:<password>@<backend_host>:<backend_port>/<database_name>``
|
||||||
|
|
||||||
|
Initialize the database
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
Once the database for Trove is created, its structure needs to be populated.
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
$ trove-manage db_sync
|
||||||
|
|
||||||
|
Create and register Trove guest image
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
To build Trove guest image, refer to
|
||||||
|
`Build guest agent image <https://docs.openstack.org/trove/latest/admin/trovestack.html#build-guest-agent-image>`_
|
||||||
|
|
||||||
|
Run Trove
|
||||||
|
~~~~~~~~~
|
||||||
|
|
||||||
|
Starting Trove services
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
Run trove-api:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
$ trove-api --config-file=${TROVE_CONF_DIR}/trove.conf &
|
||||||
|
|
||||||
|
Run trove-taskmanager:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
$ trove-taskmanager --config-file=${TROVE_CONF_DIR}/trove.conf &
|
||||||
|
|
||||||
|
Run trove-conductor:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
$ trove-conductor --config-file=${TROVE_CONF_DIR}/trove.conf &
|
@ -1,24 +0,0 @@
|
|||||||
.. _trove-install:
|
|
||||||
|
|
||||||
Install and configure
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
This section describes how to install and configure the
|
|
||||||
Database service, code-named trove, on the controller node.
|
|
||||||
|
|
||||||
This section assumes that you already have a working OpenStack
|
|
||||||
environment with at least the following components installed:
|
|
||||||
Compute, Image Service, Identity.
|
|
||||||
|
|
||||||
* If you want to do backup and restore, you also need Object Storage.
|
|
||||||
|
|
||||||
* If you want to provision datastores on block-storage volumes, you also
|
|
||||||
need Block Storage.
|
|
||||||
|
|
||||||
Note that installation and configuration vary by distribution.
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
|
|
||||||
install-obs.rst
|
|
||||||
install-rdo.rst
|
|
||||||
install-ubuntu.rst
|
|
@ -1,466 +0,0 @@
|
|||||||
.. _manual_install:
|
|
||||||
|
|
||||||
=========================
|
|
||||||
Manual Trove Installation
|
|
||||||
=========================
|
|
||||||
|
|
||||||
Objectives
|
|
||||||
==========
|
|
||||||
|
|
||||||
This document provides a step-by-step guide for manual installation of Trove with
|
|
||||||
an existing OpenStack environment for development purposes.
|
|
||||||
|
|
||||||
This document will not cover:
|
|
||||||
|
|
||||||
- OpenStack setup
|
|
||||||
- Trove service configuration
|
|
||||||
|
|
||||||
Requirements
|
|
||||||
============
|
|
||||||
|
|
||||||
A running OpenStack environment is required, including the following components:
|
|
||||||
|
|
||||||
- Compute (Nova)
|
|
||||||
- Image Service (Glance)
|
|
||||||
- Identity (Keystone)
|
|
||||||
- Network (Neutron)
|
|
||||||
- If you want to provision datastores on block-storage volumes, you also will need Block Storage (Cinder)
|
|
||||||
- If you want to do backup/restore and replication, you will also need Object Storage (Swift)
|
|
||||||
- An environment with a freshly installed Ubuntu 16.04 LTS to run Trove services.
|
|
||||||
This will be referred to as "local environment"
|
|
||||||
- AMQP service (RabbitMQ or QPID)
|
|
||||||
- MySQL (SQLite, PostgreSQL) database for Trove's internal needs, accessible from the local environment
|
|
||||||
- Certain OpenStack services must be accessible from VMs:
|
|
||||||
- Swift
|
|
||||||
|
|
||||||
- VMs must be accessible from local environment for development/debugging purposes
|
|
||||||
|
|
||||||
- OpenStack services must be accessible directly from the local environment, such as:
|
|
||||||
- Nova
|
|
||||||
- Cinder
|
|
||||||
- Swift
|
|
||||||
- Heat
|
|
||||||
|
|
||||||
Installation
|
|
||||||
============
|
|
||||||
|
|
||||||
-----------
|
|
||||||
Gather info
|
|
||||||
-----------
|
|
||||||
|
|
||||||
The following information about the existing environment is required:
|
|
||||||
|
|
||||||
- Keystone host and port(s)
|
|
||||||
- OpenStack administrator's username, tenant name and password
|
|
||||||
- Nova URL
|
|
||||||
- Cinder URL
|
|
||||||
- Swift URL
|
|
||||||
- Heat URL
|
|
||||||
- AMQP connection credentials (server URL, user, password)
|
|
||||||
- Trove's controller backend connection string (MySQL, SQLite, PostgreSQL)
|
|
||||||
|
|
||||||
--------------------
|
|
||||||
Install dependencies
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
Required packages for Trove
|
|
||||||
---------------------------
|
|
||||||
|
|
||||||
List of packages to be installed:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
$ sudo apt-get install build-essential libxslt1-dev qemu-utils mysql-client \
|
|
||||||
git python-dev python-pexpect python-pymysql libmysqlclient-dev
|
|
||||||
|
|
||||||
Python settings
|
|
||||||
---------------
|
|
||||||
|
|
||||||
To find out which setuptools version is latest please check out the `setuptools repo`_.
|
|
||||||
|
|
||||||
.. _setuptools repo: https://pypi.org/project/setuptools/
|
|
||||||
|
|
||||||
To find out which pip version is latest please visit the `pip repo`_.
|
|
||||||
|
|
||||||
.. _pip repo: https://pypi.org/project/pip/
|
|
||||||
|
|
||||||
Some packages in Ubuntu repositories are outdated. Please make sure to update to the latest versions from the appropriate sources.
|
|
||||||
|
|
||||||
Use latest setuptools:
|
|
||||||
|
|
||||||
Go https://pypi.org/project/setuptools, download the latest source setuptools, and move it under ~
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
$ cd ~
|
|
||||||
$ tar xfvz setuptools-{{latest}}.tar.gz
|
|
||||||
$ cd setuptools-{{latest}}
|
|
||||||
$ python setup.py install --user
|
|
||||||
|
|
||||||
Use latest pip:
|
|
||||||
|
|
||||||
Go https://pypi.org/project/pip, download the latest source pip, and move it under ~
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
$ tar xfvz pip-{{latest}}.tar.gz
|
|
||||||
$ cd pip-{{latest}}
|
|
||||||
$ python setup.py install --user
|
|
||||||
|
|
||||||
Note '--user' above -- we installed packages in user's home dir, in $HOME/.local/bin, so we need to add it to path:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
$ echo PATH="$HOME/.local/bin:$PATH" >> ~/.profile
|
|
||||||
$ . ~/.profile
|
|
||||||
|
|
||||||
Install virtualenv, create environment and activate it:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
$ pip install virtualenv --user
|
|
||||||
$ virtualenv --system-site-packages env
|
|
||||||
$ . env/bin/activate
|
|
||||||
|
|
||||||
Get Trove
|
|
||||||
---------
|
|
||||||
|
|
||||||
Obtain the Trove source components from OpenStack repositories:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
$ cd ~
|
|
||||||
$ git clone https://opendev.org/openstack/trove.git
|
|
||||||
$ git clone https://opendev.org/openstack/python-troveclient.git
|
|
||||||
|
|
||||||
|
|
||||||
Install Trove
|
|
||||||
=============
|
|
||||||
|
|
||||||
First, install the requirements:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
$ cd ~/trove
|
|
||||||
$ pip install -r requirements.txt -r test-requirements.txt
|
|
||||||
|
|
||||||
Then, install Trove:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
$ sudo python setup.py develop
|
|
||||||
|
|
||||||
Finally, install the Trove client:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
$ cd ~/python-troveclient
|
|
||||||
$ sudo python setup.py develop
|
|
||||||
$ cd ~
|
|
||||||
|
|
||||||
Other required OpenStack clients (python-novaclient, python-keystoneclient, etc.) should already be installed as part of the Trove requirements.
|
|
||||||
|
|
||||||
|
|
||||||
---------------------------
|
|
||||||
Prepare Trove for OpenStack
|
|
||||||
---------------------------
|
|
||||||
|
|
||||||
You will first need to create a tenant called 'trove_for_trove_usage'.
|
|
||||||
Next, create users called 'regular_trove_user' and 'admin_trove_user' —using 'trove' as the password. These are the accounts used by the Trove service.
|
|
||||||
Additionally, you will need to register Trove as an OpenStack service and its endpoints:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
$ openstack --os-username <OpenStackAdminUsername> --os-password <OpenStackAdminPassword> --os-project-name <OpenStackAdminProject> --os-domain-name <OpenstackDomainName> --os-auth-url http://<KeystoneIP>/identity project create trove_for_trove_usage
|
|
||||||
|
|
||||||
$ openstack --os-username <OpenStackAdminUsername> --os-password <OpenStackAdminPassword> --os-project-name <OpenStackAdminProject> --os-domain-name <OpenstackDomainName> --os-auth-url http://<KeystoneIP>/identity user create regular_trove_user --project trove_for_trove_usage --password-prompt
|
|
||||||
|
|
||||||
$ openstack --os-username <OpenStackAdminUsername> --os-password <OpenStackAdminPassword> --os-project-name <OpenStackAdminProject> --os-domain-name <OpenstackDomainName> --os-auth-url http://<KeystoneIP>/identity user create admin_trove_user --project trove_for_trove_usage --password-prompt
|
|
||||||
|
|
||||||
$ openstack --os-username <OpenStackAdminUsername> --os-password <OpenStackAdminPassword> --os-project-name <OpenStackAdminProject> --os-domain-name <OpenstackDomainName> --os-auth-url http://<KeystoneIP>/identity role add --user admin_trove_user --project trove_for_trove_usage admin
|
|
||||||
|
|
||||||
$ openstack --os-username <OpenStackAdminUsername> --os-password <OpenStackAdminPassword> --os-project-name <OpenStackAdminProject> --os-domain-name <OpenstackDomainName> --os-auth-url http://<KeystoneIP>/identity service create --name trove --description "Database" database
|
|
||||||
|
|
||||||
$ openstack --os-username <OpenStackAdminUsername> --os-password <OpenStackAdminPassword> --os-project-name <OpenStackAdminProject> --os-domain-name <OpenstackDomainName> --os-auth-url http://<KeystoneIP>/identity endpoint create --region RegionOne database public 'http://<EnvironmentPublicIP>:<EnvironmentPort>/v1.0/$(tenant_id)s'
|
|
||||||
|
|
||||||
$ openstack --os-username <OpenStackAdminUsername> --os-password <OpenStackAdminPassword> --os-project-name <OpenStackAdminProject> --os-domain-name <OpenstackDomainName> --os-auth-url http://<KeystoneIP>/identity endpoint create --region RegionOne database admin 'http://<EnvironmentPublicIP>:<EnvironmentPort>/v1.0/$(tenant_id)s'
|
|
||||||
|
|
||||||
$ openstack --os-username <OpenStackAdminUsername> --os-password <OpenStackAdminPassword> --os-project-name <OpenStackAdminProject> --os-domain-name <OpenstackDomainName> --os-auth-url http://<KeystoneIP>/identity endpoint create --region RegionOne database internal 'http://<EnvironmentPublicIP>:<EnvironmentPort>/v1.0/$(tenant_id)s'
|
|
||||||
|
|
||||||
Where <EnvironmentPublicIP> and <EnvironmentPort> are the IP address and Port of the server where Trove was installed. This IP should be reachable from any hosts that will be used to communicate with Trove.
|
|
||||||
|
|
||||||
Prepare Trove configuration files
|
|
||||||
=================================
|
|
||||||
|
|
||||||
There are several configuration files for Trove:
|
|
||||||
|
|
||||||
- api-paste.ini and trove.conf — For trove-api service
|
|
||||||
- trove-guestagent.conf — For trove-guestagent service
|
|
||||||
- <datastore_manager>.cloudinit — Userdata for VMs during provisioning
|
|
||||||
|
|
||||||
Cloud-init scripts are userdata that is being used for different datastore types like mysql/percona, cassandra, mongodb, redis, couchbase while provisioning new compute instances.
|
|
||||||
|
|
||||||
Samples of the above are available in ~/trove/etc/trove/ as \*.conf.sample files.
|
|
||||||
|
|
||||||
If a clean Ubuntu image is used as the source image for Trove instances, the cloud-init script must install and run guestagent in the instance.
|
|
||||||
|
|
||||||
As an alternative, one may consider creating a custom image with pre-installed and pre-configured Trove in it.
|
|
||||||
|
|
||||||
Source images
|
|
||||||
=============
|
|
||||||
|
|
||||||
As the source image for Trove instances, we will use a Trove-compatible Ubuntu image.
|
|
||||||
Build your own Trove images, Then run the following steps:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
$ export DATASTORE_TYPE="mysql"
|
|
||||||
$ glance --os-username admin_trove_user --os-password trove --os-tenant-name trove_for_trove_usage --os-auth-url http://<KeystoneIP>:<KeystoneAdminPort>/v2.0 image-create --name trove-image --is-public True --container-format ovf --disk-format qcow2 --file ${DATASTORE_TYPE}.qcow2
|
|
||||||
|
|
||||||
At this step please remember the image ID or store it in an environment variable (IMAGEID).
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
$ glance --os-username trove --os-password trove --os-tenant-name trove --os-auth-url http://<KeystoneIP>:<KeystoneAdminPort>/v2.0
|
|
||||||
image-create --name trove-image --is-public true --container-format ovf --disk-format qcow2 --owner trove < precise.qcow2
|
|
||||||
|
|
||||||
$ export IMAGEID=<glance_image_id>
|
|
||||||
|
|
||||||
|
|
||||||
Cloud-init scripts
|
|
||||||
==================
|
|
||||||
|
|
||||||
-------------------
|
|
||||||
Cloud-init location
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
By default, trove-taskmanager will look at /etc/trove/cloudinit for <datastore_manager>.cloudinit.
|
|
||||||
|
|
||||||
------------------
|
|
||||||
Cloud-init content
|
|
||||||
------------------
|
|
||||||
|
|
||||||
Each cloud-init script for Trove-compatible images should contain:
|
|
||||||
|
|
||||||
- Trove installation
|
|
||||||
|
|
||||||
Custom images with Trove code inside
|
|
||||||
====================================
|
|
||||||
|
|
||||||
*To be added*
|
|
||||||
|
|
||||||
Prepare the database
|
|
||||||
====================
|
|
||||||
|
|
||||||
Create the Trove database schema:
|
|
||||||
|
|
||||||
- Connect to the storage backend (MySQL, PostgreSQL)
|
|
||||||
- Create a database called `trove` (this database will be used for storing Trove ORM)
|
|
||||||
- Compose connection string. Example: mysql+pymysql://<user>:<password>@<backend_host>:<backend_port>/<database_name>
|
|
||||||
|
|
||||||
Initialize the database
|
|
||||||
=======================
|
|
||||||
|
|
||||||
Once the database for Trove is created, its structure needs to be populated.
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
$ trove-manage db_sync
|
|
||||||
|
|
||||||
Setup Trove Datastores
|
|
||||||
======================
|
|
||||||
|
|
||||||
---------
|
|
||||||
Datastore
|
|
||||||
---------
|
|
||||||
|
|
||||||
A Datastore is a data structure that describes a set of Datastore Versions, which consists of::
|
|
||||||
|
|
||||||
- ID -- simple auto-generated UUID
|
|
||||||
- Name -- user-defined attribute, actual name of a datastore
|
|
||||||
- Datastore Versions
|
|
||||||
|
|
||||||
|
|
||||||
Example::
|
|
||||||
|
|
||||||
- mysql, cassandra, redis, etc.
|
|
||||||
|
|
||||||
-----------------
|
|
||||||
Datastore Version
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
A Datastore Version is a data structure that describes a version of a specific database pinned to datastore, which consists of::
|
|
||||||
|
|
||||||
- ID — Simple auto-generated UUID
|
|
||||||
- Datastore ID — Reference to Datastore
|
|
||||||
- Name — User-defined attribute, actual name of a database version
|
|
||||||
- Datastore manager — trove-guestagent manager that is used for datastore management
|
|
||||||
- Image ID — Reference to a specific Glance image ID
|
|
||||||
- Packages — Operating system specific packages that would be deployed onto datastore VM
|
|
||||||
- Active — Boolean flag that defines if version can be used for instance deployment or not
|
|
||||||
|
|
||||||
Example::
|
|
||||||
|
|
||||||
- ID - edb1d22a-b66d-4e86-be60-756240439272
|
|
||||||
- Datastore ID - 9c3d890b-a2f2-4ba5-91b2-2997d0791502
|
|
||||||
- Name - mysql-5.7
|
|
||||||
- Datastore manager - mysql
|
|
||||||
- Image ID - d73a402-3953-4721-8c99-86fc72e1cb51
|
|
||||||
- Packages - mysql-server=5.7, percona-xtrabackup=2.4
|
|
||||||
- Active - True
|
|
||||||
|
|
||||||
--------------------------------------------
|
|
||||||
Datastore and Datastore Version registration
|
|
||||||
--------------------------------------------
|
|
||||||
|
|
||||||
To register a datastore, you must execute:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
$ export DATASTORE_TYPE="mysql" # available options: mysql, mongodb, postgresql, redis, cassandra, couchbase, couchdb, db2, vertica, etc.
|
|
||||||
|
|
||||||
$ export DATASTORE_VERSION="5.7" # available options: for cassandra 2.0.x, for mysql: 5.x, for mongodb: 2.x.x, etc.
|
|
||||||
|
|
||||||
$ export PACKAGES="mysql-server-5.7" # available options: cassandra=2.0.9, mongodb=2.0.4, etc
|
|
||||||
|
|
||||||
$ export IMAGEID="9910350b-77e3-4790-86be-b971d0cf9175" # Glance image ID of the relevant Datastore version (see Source images section)
|
|
||||||
|
|
||||||
$ trove-manage datastore_update ${DATASTORE_TYPE} ""
|
|
||||||
|
|
||||||
$ trove-manage datastore_version_update ${DATASTORE_TYPE} ${DATASTORE_VERSION} ${DATASTORE_TYPE} ${IMAGEID} ${PACKAGES} 1
|
|
||||||
|
|
||||||
$ trove-manage datastore_update ${DATASTORE_TYPE} ${DATASTORE_VERSION}
|
|
||||||
|
|
||||||
=========
|
|
||||||
Run Trove
|
|
||||||
=========
|
|
||||||
|
|
||||||
Trove services configuration and tuning
|
|
||||||
=======================================
|
|
||||||
|
|
||||||
*To be added*
|
|
||||||
|
|
||||||
Starting Trove services
|
|
||||||
=======================
|
|
||||||
|
|
||||||
Run trove-api:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
$ trove-api --config-file=${TROVE_CONF_DIR}/trove.conf &
|
|
||||||
|
|
||||||
Run trove-taskmanager:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
$ trove-taskmanager --config-file=${TROVE_CONF_DIR}/trove.conf &
|
|
||||||
|
|
||||||
Run trove-conductor:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
$ trove-conductor --config-file=${TROVE_CONF_DIR}/trove.conf &
|
|
||||||
|
|
||||||
=================
|
|
||||||
Trove interaction
|
|
||||||
=================
|
|
||||||
|
|
||||||
Keystonerc
|
|
||||||
==========
|
|
||||||
|
|
||||||
You need to build a `keystonerc` file that contains data to simplify the auth processes while using the Trove client:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
export OS_PROJECT_NAME=trove
|
|
||||||
|
|
||||||
export OS_USERNAME=regular_trove_user
|
|
||||||
|
|
||||||
export OS_PASSWORD=<UserPassword>
|
|
||||||
|
|
||||||
export OS_AUTH_URL="http://<KeystoneIP>/identity"
|
|
||||||
|
|
||||||
export OS_USER_DOMAIN_NAME=Default
|
|
||||||
|
|
||||||
export OS_PROJECT_DOMAIN_NAME=Default
|
|
||||||
|
|
||||||
Trove deployment verification
|
|
||||||
=============================
|
|
||||||
|
|
||||||
First you need to execute:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
$ . keystonerc
|
|
||||||
|
|
||||||
To see `help` for a specific command:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
$ trove help <command>
|
|
||||||
|
|
||||||
To create an instance:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
$ trove create <name> <flavor>
|
|
||||||
[--size <size>] [--volume_type <volume_type>]
|
|
||||||
[--databases <database> [<database> ...]]
|
|
||||||
[--users <user:password> [<user:password> ...]]
|
|
||||||
[--backup <backup>]
|
|
||||||
[--availability_zone <availability_zone>]
|
|
||||||
[--datastore <datastore>]
|
|
||||||
[--datastore_version <datastore_version>]
|
|
||||||
[--nic <net-id=<net-uuid>,v4-fixed-ip=<ip-addr>,port-id=<port-uuid>>]
|
|
||||||
[--configuration <configuration>]
|
|
||||||
[--replica_of <source_instance>] [--replica_count <count>]
|
|
||||||
[--module <module>] [--locality <policy>]
|
|
||||||
|
|
||||||
===============
|
|
||||||
Troubleshooting
|
|
||||||
===============
|
|
||||||
|
|
||||||
No instance IPs in the output of 'trove show <instance_id>'
|
|
||||||
===========================================================
|
|
||||||
|
|
||||||
If the Trove instance was successfully created, is showing ACTIVE state and working, yet there is no IP address for the instance shown in the output of 'trove show <instance_id>, then confirm the following lines are added to trove.conf ::
|
|
||||||
|
|
||||||
network_label_regex = ^NETWORK_NAME$
|
|
||||||
|
|
||||||
where NETWORK_NAME should be replaced with real name of the network to which the instance is connected to.
|
|
||||||
|
|
||||||
To decide which network would you like to attach a Trove instance to, run the following command:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
$ openstack network list
|
|
||||||
|
|
||||||
One possible way to find the network name is to execute the 'nova list' command. The output will list all OpenStack instances for the tenant, including network information. Look for ::
|
|
||||||
|
|
||||||
NETWORK_NAME=IP_ADDRESS
|
|
||||||
|
|
||||||
|
|
||||||
Additional information
|
|
||||||
======================
|
|
||||||
|
|
||||||
Additional information can be found in the OpenStack installation guide for the trove project. This document can be found under the "Installation Tutorials and Guides" section of the OpenStack Documentation.
|
|
||||||
|
|
||||||
For the current documentation, visit:
|
|
||||||
|
|
||||||
http://docs.openstack.org/index.html#install-guides
|
|
||||||
|
|
||||||
Select the link for "Installation Tutorials and Guides"
|
|
||||||
|
|
||||||
The installation guides for trove (the Database Service) can be found under the appropriate operating system.
|
|
||||||
|
|
||||||
If you are interested in documentation for a specific OpenStack release, visit:
|
|
||||||
|
|
||||||
http://docs.openstack.org/<release-code-name>/
|
|
||||||
|
|
||||||
For example, the documentation for the Pike release is found at:
|
|
||||||
|
|
||||||
http://docs.openstack.org/pike/
|
|
||||||
|
|
||||||
and the documentation for the Queens release is found at:
|
|
||||||
|
|
||||||
http://docs.openstack.org/queens/
|
|
Loading…
Reference in New Issue
Block a user