308 lines
12 KiB
Bash
Executable File
308 lines
12 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# create_config script for devstack plugin script
|
|
# Build config for run functional tests with or wuthout tempest
|
|
|
|
set -o xtrace
|
|
set +o errexit
|
|
|
|
TEST_CONFIG="$1"
|
|
if [[ -z "$TEST_CONFIG" ]]; then
|
|
die $LINENO "Please pass config name"
|
|
fi
|
|
sudo rm -f $EC2API_DIR/$TEST_CONFIG
|
|
|
|
REGULAR_IMAGE_URL="https://cloud-images.ubuntu.com/precise/current/precise-server-cloudimg-i386-disk1.img"
|
|
REGULAR_IMAGE_FNAME="precise-server-cloudimg-i386-disk1.img"
|
|
REGULAR_IMAGE_NAME="precise"
|
|
|
|
CIRROS_IMAGE_URL="http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img"
|
|
CIRROS_IMAGE_FNAME="cirros-0.3.4-x86_64-disk.img"
|
|
CIRROS_IMAGE_NAME="cirros"
|
|
|
|
MAX_FAIL=20
|
|
FLAVOR_NAME="m1.ec2api"
|
|
FLAVOR_NAME_ALT="m1.ec2api-alt"
|
|
|
|
if [[ -n "$TOP_DIR" ]]; then
|
|
source $TOP_DIR/openrc admin admin
|
|
unset OS_CLOUD
|
|
#unset OS_AUTH_TYPE
|
|
fi
|
|
|
|
openstack endpoint list
|
|
if [[ "$?" -ne "0" ]]; then
|
|
die $LINENO "OpenStack CLI doesn't work. Looks like credentials are absent."
|
|
fi
|
|
|
|
EC2_URL=`openstack endpoint list --service ec2 --interface public --os-identity-api-version=3 -c URL -f value`
|
|
S3_URL=`openstack endpoint list --service s3 --interface public --os-identity-api-version=3 -c URL -f value`
|
|
|
|
venv_dir="$(pwd)/.venv_awscli"
|
|
virtualenv "$venv_dir"
|
|
if [[ "$?" -ne "0" ]]; then
|
|
die $LINENO "Can't setup virtual env."
|
|
fi
|
|
source "$venv_dir/bin/activate"
|
|
pip install awscli
|
|
if [[ "$?" -ne "0" ]]; then
|
|
die $LINENO "Can't install awscli in virtual env."
|
|
fi
|
|
aws --version
|
|
if [[ "$?" -ne "0" ]]; then
|
|
die $LINENO "awscli doesn't work correctly."
|
|
fi
|
|
deactivate
|
|
|
|
project_id=`openstack project show $OS_PROJECT_NAME -c id -f value`
|
|
openstack ec2 credentials create 1>&2
|
|
line=`openstack ec2 credentials list | grep " $project_id "`
|
|
read ec2_access_key ec2_secret_key <<< `echo $line | awk '{print $2 " " $4 }'`
|
|
source "$venv_dir/bin/activate"
|
|
aws configure set aws_access_key_id $ec2_access_key --profile admin
|
|
aws configure set aws_secret_access_key $ec2_secret_key --profile admin
|
|
deactivate
|
|
AWS_PARAMS="--region $REGION_NAME --endpoint-url $EC2_URL"
|
|
|
|
neutron_item=$(openstack service list | grep neutron)
|
|
|
|
# prepare flavors
|
|
openstack flavor create --public --id 16 --ram 512 --disk 1 --vcpus 1 $FLAVOR_NAME
|
|
openstack flavor create --public --id 17 --ram 256 --disk 1 --vcpus 1 $FLAVOR_NAME_ALT
|
|
|
|
# prepare cirros image for register_image test. uploading it to S3.
|
|
sudo rm /tmp/$CIRROS_IMAGE_FNAME
|
|
wget -nv -P /tmp $CIRROS_IMAGE_URL &
|
|
cirros_image_wget_pid=$!
|
|
|
|
# find simple image
|
|
source "$venv_dir/bin/activate"
|
|
image_id=`aws $AWS_PARAMS --profile admin ec2 describe-images --filters Name=image-type,Values=machine Name=name,Values=cirros* --query 'Images[0].ImageId' --output text`
|
|
deactivate
|
|
|
|
if [[ "$image_id" == 'None' || -z "$image_id" ]]; then
|
|
wait $cirros_image_wget_pid
|
|
if [[ "$?" -eq "0" ]]; then
|
|
openstack image create --disk-format raw --container-format bare --public --file /tmp/$CIRROS_IMAGE_FNAME $CIRROS_IMAGE_NAME
|
|
if [[ "$?" -ne "0" ]]; then
|
|
echo "Creation of openstack image failed."
|
|
fi
|
|
source "$venv_dir/bin/activate"
|
|
image_id=`aws $AWS_PARAMS --profile admin ec2 describe-images --filters Name=image-type,Values=machine Name=name,Values=cirros* --query 'Images[0].ImageId' --output text`
|
|
deactivate
|
|
fi
|
|
fi
|
|
|
|
# prepare ubuntu image
|
|
if [[ $RUN_LONG_TESTS == "1" ]]; then
|
|
sudo rm /tmp/$REGULAR_IMAGE_FNAME
|
|
wget -nv -P /tmp $REGULAR_IMAGE_URL
|
|
if [[ "$?" -ne "0" ]]; then
|
|
echo "Downloading of precise image failed."
|
|
exit 1
|
|
fi
|
|
openstack image create --disk-format raw --container-format bare --public --file /tmp/$REGULAR_IMAGE_FNAME $REGULAR_IMAGE_NAME
|
|
if [[ "$?" -ne "0" ]]; then
|
|
echo "Creation of precise image failed."
|
|
exit 1
|
|
fi
|
|
# find this image
|
|
source "$venv_dir/bin/activate"
|
|
image_id_ubuntu=`aws $AWS_PARAMS --profile admin ec2 describe-images --filters Name=image-type,Values=machine Name=name,Values=$REGULAR_IMAGE_NAME --query 'Images[0].ImageId' --output text`
|
|
deactivate
|
|
fi
|
|
|
|
# create separate user/project
|
|
project_name="project-$(cat /dev/urandom | tr -cd 'a-f0-9' | head -c 8)"
|
|
eval $(openstack project create -f shell -c id $project_name)
|
|
project_id=$id
|
|
[[ -n "$project_id" ]] || { echo "Can't create project"; exit 1; }
|
|
user_name="user-$(cat /dev/urandom | tr -cd 'a-f0-9' | head -c 8)"
|
|
eval $(openstack user create "$user_name" --project "$project_id" --password "password" --email "$user_name@example.com" -f shell -c id)
|
|
user_id=$id
|
|
[[ -n "$user_id" ]] || { echo "Can't create user"; exit 1; }
|
|
# add 'Member' role for swift access
|
|
role_id=$(openstack role show Member -c id -f value)
|
|
openstack role add --project $project_id --user $user_id $role_id
|
|
# create network
|
|
if [[ -n "$neutron_item" ]]; then
|
|
net_id=$(openstack network create --project $project_id private | grep ' id ' | awk '{print $4}')
|
|
[[ -n "$net_id" ]] || { echo "net-create failed"; exit 1; }
|
|
subnet_id=$(openstack subnet create --project $project_id --ip-version 4 --gateway 10.0.0.1 --network $net_id --subnet-range 10.0.0.0/24 private_subnet | grep ' id ' | awk '{print $4}')
|
|
[[ -n "$subnet_id" ]] || { echo "subnet-create failed"; exit 1; }
|
|
router_id=$(openstack router create --project $project_id private_router | grep ' id ' | awk '{print $4}')
|
|
[[ -n "$router_id" ]] || { echo "router-create failed"; exit 1; }
|
|
sleep 2
|
|
openstack router add subnet $router_id $subnet_id
|
|
[[ "$?" -eq 0 ]] || { echo "router-interface-add failed"; exit 1; }
|
|
public_net_id=$(openstack network list | awk '/public/{print $2}')
|
|
[[ -n "$public_net_id" ]] || { echo "can't find public network"; exit 1; }
|
|
openstack router set --external-gateway $public_net_id $router_id
|
|
[[ "$?" -eq 0 ]] || { echo "router-gateway-set failed"; exit 1; }
|
|
fi
|
|
# populate credentials
|
|
openstack ec2 credentials create --user $user_id --project $project_id 1>&2
|
|
line=`openstack ec2 credentials list --user $user_id | grep " $project_id "`
|
|
read ec2_access_key ec2_secret_key <<< `echo $line | awk '{print $2 " " $4 }'`
|
|
source "$venv_dir/bin/activate"
|
|
aws configure set aws_access_key_id $ec2_access_key --profile user
|
|
aws configure set aws_secret_access_key $ec2_secret_key --profile user
|
|
deactivate
|
|
|
|
env|sort
|
|
auth="--os-project-name $project_name --os-username $user_name --os-password password"
|
|
|
|
# create EBS image
|
|
volume_status() { openstack $auth volume show $1 | awk '/ status / {print $4}'; }
|
|
instance_status() { openstack $auth server show $1 | awk '/ status / {print $4}'; }
|
|
|
|
openstack_image_id=$(openstack $auth image list --long | grep "cirros" | grep " bare " | head -1 | awk '{print $2}')
|
|
if [[ -n "$openstack_image_id" ]]; then
|
|
volume_name="vol-$(cat /dev/urandom | tr -cd 'a-f0-9' | head -c 8)"
|
|
volume_id=$(openstack $auth volume create --image $openstack_image_id --size 1 $volume_name | awk '/ id / {print $4}')
|
|
[[ -n "$volume_id" ]] || { echo "can't create volume for EBS image creation"; exit 1; }
|
|
fail=0
|
|
while [[ true ]] ; do
|
|
if ((fail >= MAX_FAIL)); then
|
|
die $LINENO "Volume creation fails (timeout)"
|
|
fi
|
|
echo "attempt "$fail" of "$MAX_FAIL
|
|
status=$(volume_status $volume_id)
|
|
if [[ $status == "available" ]]; then
|
|
break
|
|
fi
|
|
if [[ $status == "error" || -z "$status" ]]; then
|
|
openstack $auth volume show $volume_id
|
|
die $LINENO 'Volume creation error'
|
|
fi
|
|
sleep 10
|
|
((++fail))
|
|
done
|
|
|
|
instance_name="i-$(cat /dev/urandom | tr -cd 'a-f0-9' | head -c 8)"
|
|
instance_id=$(nova $auth boot \
|
|
--flavor "$FLAVOR_NAME" \
|
|
--nic net-id=$net_id \
|
|
--block-device "device=/dev/vda,id=$volume_id,shutdown=remove,source=volume,dest=volume,bootindex=0" \
|
|
"$instance_name" | awk '/ id / {print $4}')
|
|
# TODO: find a way how to run with delete-on-terminate or set it after run with openstack client
|
|
# instance_id=$(openstack $auth server create \
|
|
# --flavor "$FLAVOR_NAME" \
|
|
# --volume $volume_id \
|
|
# --nic net-id=$net_id \
|
|
# "$instance_name" | awk '/ id / {print $4}')
|
|
[[ -n "$instance_id" ]] || { echo "can't boot EBS instance"; exit 1; }
|
|
fail=0
|
|
while [[ true ]] ; do
|
|
if ((fail >= MAX_FAIL)); then
|
|
die $LINENO "Instance active status wait timeout occurred"
|
|
fi
|
|
echo "attempt "$fail" of "$MAX_FAIL
|
|
status=$(instance_status $instance_id)
|
|
if [[ "$status" == "ACTIVE" ]]; then
|
|
break
|
|
fi
|
|
if [[ "$status" == "ERROR" || -z "$status" ]]; then
|
|
openstack $auth server show $instance_id
|
|
die $LINENO 'Instance booting error'
|
|
fi
|
|
sleep 10
|
|
((++fail))
|
|
done
|
|
|
|
image_name="image-$(cat /dev/urandom | tr -cd 'a-f0-9' | head -c 8)"
|
|
openstack $auth server image create --name $image_name --wait $instance_name
|
|
if [[ "$?" -ne "0" ]]; then
|
|
die $LINENO "Image creation from instance fails"
|
|
fi
|
|
source "$venv_dir/bin/activate"
|
|
ebs_image_id=`aws $AWS_PARAMS --profile user ec2 describe-images --filters Name=image-type,Values=machine Name=name,Values=$image_name --query 'Images[0].ImageId' --output text`
|
|
deactivate
|
|
openstack $auth server delete $instance_id
|
|
fi
|
|
|
|
timeout="180"
|
|
run_long_tests="False"
|
|
if [[ $RUN_LONG_TESTS == "1" ]]; then
|
|
timeout="600"
|
|
run_long_tests="True"
|
|
fi
|
|
|
|
# right now nova-network is very unstable to run tests that want to ssh into instance
|
|
run_ssh="False"
|
|
if [[ -n "$neutron_item" ]]; then
|
|
run_ssh="True"
|
|
fi
|
|
|
|
wait $cirros_image_wget_pid
|
|
if [[ "$?" -eq "0" && "$CA_CERT" && -e "$CA_CERT" ]]; then
|
|
sudo apt-get -fy install ruby
|
|
ID="$(cat /dev/urandom | tr -cd 'a-f0-9' | head -c 8)"
|
|
WORKING_DIR="/tmp/bi-$ID"
|
|
mkdir -p $WORKING_DIR
|
|
wget -t 2 -T 60 -q -P $WORKING_DIR http://s3.amazonaws.com/ec2-downloads/ec2-ami-tools.zip
|
|
unzip -d $WORKING_DIR $WORKING_DIR/ec2-ami-tools.zip
|
|
TOOLS_DIR="$WORKING_DIR/$(ls $WORKING_DIR | grep -Eo "ec2-ami-tools-[0-9\.]*")"
|
|
|
|
IMAGES_DIR="$WORKING_DIR/images"
|
|
# IMPORTANT! bucket name should contain '.' - in this case ami-tools will not build s3 url with bucket name.
|
|
AWS_AMI_BUCKET="tmp-bundle.$ID"
|
|
|
|
EC2_USER_ID=42424242424242 # ec2api does not use user id, but bundling requires it
|
|
EC2_PRIVATE_KEY="$WORKING_DIR/private/pk.pem"
|
|
EC2_CSR="$WORKING_DIR/cert.csr"
|
|
EC2_CERT="$WORKING_DIR/cert.pem"
|
|
|
|
mkdir -p "$WORKING_DIR/private/"
|
|
|
|
# generate user certificate
|
|
openssl genrsa -out "$EC2_PRIVATE_KEY" 2048
|
|
openssl req -new -key "$EC2_PRIVATE_KEY" -subj "/C=RU/ST=Moscow/L=Moscow/O=Progmatic/CN=functional-tests" -out "$EC2_CSR"
|
|
openssl x509 -req -in "$EC2_CSR" -CA "$CA_CERT" -CAkey "$CA_KEY" -CAcreateserial -out "$EC2_CERT" -days 365
|
|
|
|
mkdir -p "$IMAGES_DIR"
|
|
$TOOLS_DIR/bin/ec2-bundle-image --cert $EC2_CERT --privatekey $EC2_PRIVATE_KEY --ec2cert $CA_CERT --image /tmp/$CIRROS_IMAGE_FNAME --prefix $CIRROS_IMAGE_FNAME --user $EC2_USER_ID --destination "$IMAGES_DIR" --arch x86_64
|
|
if [[ "$?" -eq "0" ]]; then
|
|
$TOOLS_DIR/bin/ec2-upload-bundle --url "$S3_URL" --access-key $ec2_access_key --secret-key $ec2_secret_key --bucket "$AWS_AMI_BUCKET" --manifest "$IMAGES_DIR/$CIRROS_IMAGE_FNAME.manifest.xml" --acl "public-read" --sigv 2
|
|
if [[ "$?" -eq "0" ]]; then
|
|
cirros_image_manifest="$AWS_AMI_BUCKET/$CIRROS_IMAGE_FNAME.manifest.xml"
|
|
else
|
|
warn $LINENO "Uploading of image $CIRROS_IMAGE_URL to S3 failed."
|
|
fi
|
|
else
|
|
warn $LINENO "Bundling of image $CIRROS_IMAGE_URL failed."
|
|
fi
|
|
# next line is example how to register this image in the cloud
|
|
#source "$venv_dir/bin/activate"
|
|
#aws --endpoint-url $EC2_URL --region RegionOne --profile admin ec2 register-image --image-location "$AWS_AMI_BUCKET/$CIRROS_IMAGE_FNAME.manifest.xml" --name "$CIRROS_IMAGE_FNAME" --architecture x86_64
|
|
#deactivate
|
|
else
|
|
warn $LINENO "Downloading of image $CIRROS_IMAGE_URL failed."
|
|
fi
|
|
|
|
vpnaas_enabled='False'
|
|
if openstack extension list | grep -q " vpnaas " ; then
|
|
vpnaas_enabled='True'
|
|
fi
|
|
|
|
sudo bash -c "cat > $EC2API_DIR/$TEST_CONFIG <<EOF
|
|
[aws]
|
|
ec2_url = $EC2_URL
|
|
s3_url = $S3_URL
|
|
aws_access = $ec2_access_key
|
|
aws_secret = $ec2_secret_key
|
|
image_id = $image_id
|
|
image_id_ubuntu = $image_id_ubuntu
|
|
ebs_image_id = $ebs_image_id
|
|
build_timeout = $timeout
|
|
run_long_tests = $run_long_tests
|
|
instance_type = $FLAVOR_NAME
|
|
instance_type_alt = $FLAVOR_NAME_ALT
|
|
ami_image_location = $cirros_image_manifest
|
|
run_ssh = $run_ssh
|
|
vpnaas_enabled = $vpnaas_enabled
|
|
ca_bundle = $OS_CACERT
|
|
EOF"
|
|
|
|
sudo chown -f $STACK_USER $EC2API_DIR/$TEST_CONFIG
|