465 lines
16 KiB
Bash
Executable File
465 lines
16 KiB
Bash
Executable File
#!/bin/bash -ex
|
|
|
|
# Deploys CCP and runs simple, built-in OpenStack tests.
|
|
# Kubernetes cluster is expected to be pre-deployed and snapshoted - if not
|
|
# this script will ensure this.
|
|
# The script expects fuel-ccp cloned into fuel-ccp/ and fuel-ccp-installer
|
|
# cloned into fuel-ccp-installer/ directory (e.g. by Jenkins SCM plugin).
|
|
|
|
# CONFIGURATION:
|
|
######################################################
|
|
: ${FUEL_DEVOPS_ENV_NAME:="fuel-ccp-${COMPONENT}-${VERSION}-deployment"}
|
|
FUEL_DEVOPS_SNAPSHOT_NAME="fresh"
|
|
FUEL_DEVOPS_INSTALLATION_DIR="/home/jenkins/venv-fuel-devops-3.0"
|
|
HYPERKUBE_REPO="quay.io/coreos/hyperkube"
|
|
HYPERKUBE_TAG="v1.5.1_coreos.0"
|
|
HYPERKUBE_VERSION="v1.5.1"
|
|
export APT_CACHE_SERVER_IP="`getent hosts cache-scc.ng.mirantis.net| awk '{print $1}'`"
|
|
export APT_CACHE_SERVER_PORT="3142"
|
|
export REGISTRY_IP=`ip -4 addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'`
|
|
export REGISTRY_PORT=5000
|
|
JENKINS_GID=`getent group jenkins | cut -d":" -f3`
|
|
REGISTRY_HASH=`docker inspect --format "{{.Id}}" registry`
|
|
export DOCKER_REGISTRY_HOST="registry.mcp.fuel-infra.org"
|
|
export DOCKER_REGISTRY="${DOCKER_REGISTRY_HOST}:6000"
|
|
export DOCKER_REGISTRY_IP="`getent hosts ${DOCKER_REGISTRY_HOST} | awk '{print $1}'`"
|
|
export IMAGES_NAMESPACE="ccp"
|
|
export REGISTRY_NAMESPACE="mcp"
|
|
export SHARE_HOST="share01-scc.ng.mirantis.net"
|
|
export SHARE_IP="`getent hosts ${SHARE_HOST} | awk '{print $1}'`"
|
|
|
|
function prepare_k8s_env {
|
|
# Prepare K8s env:
|
|
source "${FUEL_DEVOPS_INSTALLATION_DIR}"/bin/activate
|
|
NEED_TO_SETUP_ENV=false
|
|
dos.py revert "${FUEL_DEVOPS_ENV_NAME}" "${FUEL_DEVOPS_SNAPSHOT_NAME}" || NEED_TO_SETUP_ENV=true
|
|
dos.py resume "${FUEL_DEVOPS_ENV_NAME}" || NEED_TO_SETUP_ENV=true
|
|
if [ "${NEED_TO_SETUP_ENV}" = "true" ]; then
|
|
echo "Couldn't revert fuel-devops snapshot, recreating environment."
|
|
|
|
# Try to delete old envs to ensure clean host:
|
|
dos.py destroy "${FUEL_DEVOPS_ENV_NAME}" || true
|
|
dos.py erase "${FUEL_DEVOPS_ENV_NAME}" || true
|
|
|
|
# Create kargo deployment script:
|
|
cat > k8s_deploy.sh << EOF
|
|
#!/bin/bash -ex
|
|
|
|
export ENV_NAME=${FUEL_DEVOPS_ENV_NAME}
|
|
export IMAGE_PATH="/home/jenkins/workspace/cloud-images/default-image.qcow2"
|
|
export DONT_DESTROY_ON_SUCCESS=1
|
|
export DEPLOY_METHOD="kargo"
|
|
export SLAVES_COUNT="3"
|
|
export ADMIN_NODE_CPU=5
|
|
export ADMIN_NODE_MEMORY=14336
|
|
export SLAVE_NODE_CPU=3
|
|
export SLAVE_NODE_MEMORY=8192
|
|
export WORKSPACE="/home/jenkins/workspace"
|
|
export FUEL_DEVOPS_INSTALLATION_DIR=${FUEL_DEVOPS_INSTALLATION_DIR}
|
|
export CUSTOM_YAML='hyperkube_image_repo: "${HYPERKUBE_REPO}"
|
|
hyperkube_image_tag: "${HYPERKUBE_TAG}"
|
|
kube_version: "${HYPERKUBE_VERSION}"
|
|
docker_options: "--insecure-registry=${REGISTRY_IP}:${REGISTRY_PORT} --insecure-registry=DOCKER_REGISTRY"'
|
|
echo "Running on \${NODE_NAME}: \${ENV_NAME}"
|
|
source \${FUEL_DEVOPS_INSTALLATION_DIR}/bin/activate
|
|
echo "Use image:"
|
|
ls -la \${IMAGE_PATH}
|
|
env
|
|
pushd fuel-ccp-installer
|
|
bash -ex "./utils/jenkins/run_k8s_deploy_test.sh"
|
|
popd
|
|
EOF
|
|
chmod +x k8s_deploy.sh
|
|
|
|
# Now deploy the cluster:
|
|
./k8s_deploy.sh
|
|
|
|
# Create fresh snapshot:
|
|
dos.py suspend "${FUEL_DEVOPS_ENV_NAME}"
|
|
dos.py snapshot "${FUEL_DEVOPS_ENV_NAME}" "${FUEL_DEVOPS_SNAPSHOT_NAME}"
|
|
|
|
# Resume from snapshot to deploy CCP later on in the script:
|
|
dos.py resume "${FUEL_DEVOPS_ENV_NAME}"
|
|
fi
|
|
}
|
|
|
|
|
|
function fix_restored_env {
|
|
|
|
# After restore snapshot ntp service doesn't work and need restart on all nodes
|
|
${SSH_COMMAND} "sudo service ntp restart"
|
|
${SSH_COMMAND} "ssh -o StrictHostKeyChecking=no node2 sudo service ntp restart"
|
|
${SSH_COMMAND} "ssh -o StrictHostKeyChecking=no node3 sudo service ntp restart"
|
|
|
|
|
|
# Dirty hack for workaround network problems on CI envs.
|
|
# When we deploy env some time after (few minutes) it change resolv.conf into broken one
|
|
# From this reason after bring up env we restart network and and kill dhclient,
|
|
# we also restart docker and kubelet to make sure that all net-host containers are in good shape
|
|
|
|
cat > fix_dns.sh << EOF
|
|
sudo service networking restart
|
|
sudo pkill -9 dhclient
|
|
sudo service kubelet restart
|
|
sudo service docker restart
|
|
EOF
|
|
|
|
chmod +x fix_dns.sh
|
|
|
|
${SCP_COMMAND} fix_dns.sh vagrant@"${ADMIN_IP}":~/
|
|
${SSH_COMMAND} "scp -o StrictHostKeyChecking=no fix_dns.sh vagrant@node2:~/"
|
|
${SSH_COMMAND} "scp -o StrictHostKeyChecking=no fix_dns.sh vagrant@node3:~/"
|
|
${SSH_COMMAND} "sudo ./fix_dns.sh"
|
|
${SSH_COMMAND} "ssh -o StrictHostKeyChecking=no node2 sudo ./fix_dns.sh"
|
|
${SSH_COMMAND} "ssh -o StrictHostKeyChecking=no node3 sudo ./fix_dns.sh"
|
|
|
|
}
|
|
|
|
function copy_code_to_vm {
|
|
# Prepare env on "admin" VM:
|
|
if [ ${COMPONENT} == "full" ]; then
|
|
${SCP_COMMAND} -r fuel-ccp/ vagrant@"${ADMIN_IP}":~/
|
|
elif [ ${COMPONENT} == "smoke" ]; then
|
|
${SCP_COMMAND} -r fuel-ccp/ vagrant@"${ADMIN_IP}":~/
|
|
else
|
|
${SCP_COMMAND} -r fuel-ccp/ vagrant@"${ADMIN_IP}":~/
|
|
# set +x is just for security reasons to avoid publishing internal IP
|
|
set +x
|
|
getent hosts zuul.mcp.fuel-infra.org | ${SSH_COMMAND} "sudo tee -a /etc/hosts"
|
|
set -x
|
|
${SCP_COMMAND} -r containers/openstack/ vagrant@"${ADMIN_IP}":/tmp/ccp-repos
|
|
fi
|
|
}
|
|
|
|
|
|
function prepare_ccp_config {
|
|
cat > ccp.yml << EOF
|
|
builder:
|
|
push: True
|
|
workers: 1
|
|
registry:
|
|
address: "${REGISTRY_IP}:${REGISTRY_PORT}"
|
|
timeout: 1500
|
|
replicas:
|
|
etcd: 3
|
|
database: 3
|
|
rpc: 3
|
|
notifications: 1
|
|
repositories:
|
|
path: /tmp/ccp-repos
|
|
skip_empty: True
|
|
entrypoint_repo_name: entrypoint
|
|
repos:
|
|
- git_url: https://git.openstack.org/openstack/fuel-ccp-debian-base
|
|
name: debian-base
|
|
- git_url: https://git.openstack.org/openstack/fuel-ccp-entrypoint
|
|
name: entrypoint
|
|
- git_url: https://git.openstack.org/openstack/fuel-ccp-etcd
|
|
name: etcd
|
|
- git_url: https://git.openstack.org/openstack/fuel-ccp-galera
|
|
name: galera
|
|
- git_url: https://git.openstack.org/openstack/fuel-ccp-glance
|
|
name: glance
|
|
- git_url: https://git.openstack.org/openstack/fuel-ccp-heat
|
|
name: heat
|
|
- git_url: https://git.openstack.org/openstack/fuel-ccp-horizon
|
|
name: horizon
|
|
- git_url: https://git.openstack.org/openstack/fuel-ccp-keystone
|
|
name: keystone
|
|
- git_url: https://git.openstack.org/openstack/fuel-ccp-memcached
|
|
name: memcached
|
|
- git_url: https://git.openstack.org/openstack/fuel-ccp-neutron
|
|
name: neutron
|
|
- git_url: https://git.openstack.org/openstack/fuel-ccp-nova
|
|
name: nova
|
|
- git_url: https://git.openstack.org/openstack/fuel-ccp-nginx
|
|
name: nginx
|
|
- git_url: https://git.openstack.org/openstack/fuel-ccp-openstack-base
|
|
name: openstack-base
|
|
- git_url: https://git.openstack.org/openstack/fuel-ccp-rabbitmq
|
|
name: rabbitmq
|
|
- git_url: https://git.openstack.org/openstack/fuel-ccp-ceph
|
|
name: ceph
|
|
- git_url: https://git.openstack.org/openstack/fuel-ccp-ironic
|
|
name: ironic
|
|
- git_url: https://git.openstack.org/openstack/fuel-ccp-rally
|
|
name: rally
|
|
|
|
configs:
|
|
private_interface: ens3
|
|
public_interface: ens4
|
|
neutron:
|
|
physnets:
|
|
- name: "physnet1"
|
|
bridge_name: "br-ex"
|
|
interface: "ens4"
|
|
flat: true
|
|
vlan_range: "1001:1030"
|
|
dpdk: false
|
|
etcd:
|
|
tls:
|
|
enabled: false
|
|
rally:
|
|
tempest:
|
|
openstack_release: ${VERSION}
|
|
nodes:
|
|
node[1-3]:
|
|
roles:
|
|
- controller-net-bridge
|
|
node1:
|
|
roles:
|
|
- db
|
|
- messaging
|
|
- openvswitch
|
|
- controller-net-host
|
|
node[2-3]:
|
|
roles:
|
|
- db
|
|
- messaging
|
|
- openvswitch
|
|
- compute
|
|
sources:
|
|
openstack/cinder:
|
|
git_url: https://git.openstack.org/openstack/cinder.git
|
|
git_ref: ${BRANCH}
|
|
openstack/ironic:
|
|
git_url: https://git.openstack.org/openstack/ironic.git
|
|
git_ref: ${BRANCH}
|
|
openstack/murano:
|
|
git_url: https://git.openstack.org/openstack/murano.git
|
|
git_ref: ${BRANCH}
|
|
openstack/murano-dashboard:
|
|
git_url: https://git.openstack.org/openstack/murano-dashboard.git
|
|
git_ref: ${BRANCH}
|
|
openstack/sahara:
|
|
git_url: https://git.openstack.org/openstack/sahara.git
|
|
git_ref: ${BRANCH}
|
|
openstack/sahara-dashboard:
|
|
git_url: https://git.openstack.org/openstack/sahara-dashboard.git
|
|
git_ref: ${BRANCH}
|
|
openstack/keystone:
|
|
git_url: https://git.openstack.org/openstack/keystone.git
|
|
git_ref: ${BRANCH}
|
|
openstack/horizon:
|
|
git_url: https://git.openstack.org/openstack/horizon.git
|
|
git_ref: ${BRANCH}
|
|
openstack/nova:
|
|
git_url: https://git.openstack.org/openstack/nova.git
|
|
git_ref: ${BRANCH}
|
|
openstack/neutron:
|
|
git_url: https://git.openstack.org/openstack/neutron.git
|
|
git_ref: ${BRANCH}
|
|
openstack/networking-odl:
|
|
git_url: https://git.openstack.org/openstack/networking-odl.git
|
|
git_ref: ${BRANCH}
|
|
openstack/heat:
|
|
git_url: https://git.openstack.org/openstack/heat.git
|
|
git_ref: ${BRANCH}
|
|
openstack/glance:
|
|
git_url: https://git.openstack.org/openstack/glance.git
|
|
git_ref: ${BRANCH}
|
|
openstack/requirements:
|
|
git_url: https://git.openstack.org/openstack/requirements.git
|
|
git_ref: ${BRANCH}
|
|
services:
|
|
database:
|
|
service_def: galera
|
|
rpc:
|
|
service_def: rabbitmq
|
|
notifications:
|
|
service_def: rabbitmq
|
|
roles:
|
|
db:
|
|
- database
|
|
messaging:
|
|
- rpc
|
|
- notifications
|
|
controller-net-host:
|
|
- neutron-dhcp-agent
|
|
- neutron-l3-agent
|
|
- neutron-metadata-agent
|
|
controller-net-bridge:
|
|
- etcd
|
|
- glance-api
|
|
- glance-registry
|
|
- heat-api-cfn
|
|
- heat-api
|
|
- heat-engine
|
|
- horizon
|
|
- keystone
|
|
- memcached
|
|
- neutron-server
|
|
- nova-api
|
|
- nova-conductor
|
|
- nova-consoleauth
|
|
- nova-novncproxy
|
|
- nova-scheduler
|
|
compute:
|
|
- nova-compute
|
|
- nova-libvirt
|
|
openvswitch:
|
|
- neutron-openvswitch-agent
|
|
- openvswitch-db
|
|
- openvswitch-vswitchd
|
|
|
|
EOF
|
|
}
|
|
|
|
ccp_wait_for_deployment_to_finish () {
|
|
cnt=0
|
|
until [[ `${SSH_COMMAND} ccp status -s -f value -c status` == "ok" ]]; do
|
|
echo "Waiting for OpenStack deployment to finish..."
|
|
sleep 5
|
|
cnt=$((cnt + 1))
|
|
if [ ${cnt} -eq $1 ]; then
|
|
echo "Max time exceeded"
|
|
${SSH_COMMAND} ccp status
|
|
${SSH_COMMAND} fuel-ccp/tools/diagnostic-snapshot.sh -n ccp -c ccp.yml
|
|
return 1
|
|
fi
|
|
done
|
|
echo "...................................."
|
|
echo "Jobs and pods in namespace: ccp"
|
|
${SSH_COMMAND} kubectl --namespace ccp get jobs
|
|
${SSH_COMMAND} kubectl --namespace ccp get pods
|
|
echo "openrc file: openrc-ccp"
|
|
${SSH_COMMAND} cat openrc-ccp
|
|
echo "...................................."
|
|
}
|
|
|
|
function ccp_install {
|
|
${SSH_COMMAND} "sudo -H pip install -r fuel-ccp/requirements.txt"
|
|
${SSH_COMMAND} "sudo -H pip install fuel-ccp/"
|
|
}
|
|
|
|
|
|
function deploy_ccp {
|
|
pwd
|
|
${SSH_COMMAND} "ccp -vvv --debug --config-file ~/ccp.yml build -c etcd memcached rabbitmq galera percona rabbitmq"
|
|
${SSH_COMMAND} "ccp -vvv --debug --config-file ~/ccp.yml deploy -c etcd memcached database rpc notifications"
|
|
ccp_wait_for_deployment_to_finish 70
|
|
if [ $? -ne 0 ]; then
|
|
return 1
|
|
fi
|
|
${SSH_COMMAND} "ccp -vvv --debug --config-file ~/ccp.yml build"
|
|
${SSH_COMMAND} "ccp -vvv --debug --config-file ~/ccp.yml deploy"
|
|
ccp_wait_for_deployment_to_finish 200
|
|
if [ $? -ne 0 ]; then
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
prepare_k8s_env
|
|
|
|
|
|
# Get IP address of first node in the cluster:
|
|
ADMIN_IP=$(ENV_NAME=${FUEL_DEVOPS_ENV_NAME} python fuel-ccp-installer/utils/jenkins/env.py get_slaves_ips | grep -o "[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+" | head -1)
|
|
SSH_COMMAND="sshpass -p vagrant ssh -o StrictHostKeyChecking=no vagrant@${ADMIN_IP}"
|
|
SCP_COMMAND="sshpass -p vagrant scp -o StrictHostKeyChecking=no"
|
|
|
|
# remove old key:
|
|
ssh-keygen -R "${ADMIN_IP}"
|
|
|
|
# Let's wait 5 sec to all vms up
|
|
sleep 5
|
|
|
|
# Store info about Jenkins job on VM:
|
|
echo "${BUILD_TAG}" | ${SSH_COMMAND} "tee -a JENKINS_INFO.TXT"
|
|
|
|
fix_restored_env
|
|
copy_code_to_vm
|
|
|
|
|
|
|
|
# set version of openstack
|
|
if [ "${VERSION}" == "master" ];then
|
|
export IMAGES_TAG="latest"
|
|
export BRANCH="master"
|
|
elif [ "${VERSION}" == "ocata" ];then
|
|
export IMAGES_TAG="ocata"
|
|
export BRANCH="stable/ocata"
|
|
elif [ "${VERSION}" == "newton" ]; then
|
|
export IMAGES_TAG="newton"
|
|
export BRANCH="stable/newton"
|
|
else
|
|
export IMAGES_TAG="mitaka"
|
|
export BRANCH="stable/mitaka"
|
|
fi
|
|
|
|
prepare_ccp_config
|
|
|
|
ccp_install
|
|
|
|
if [ ${COMPONENT} == "smoke" ]; then
|
|
sshpass -p vagrant ssh -o StrictHostKeyChecking=no vagrant@"${ADMIN_IP}" "echo ${SHARE_IP} ${SHARE_HOST} |sudo tee -a /etc/hosts"
|
|
set +e
|
|
ssh -i ~/.ssh/jenkins_storage share@share01-scc.ng.mirantis.net rm /srv/static/share/tests/tests/result-${VERSION}.xml
|
|
set -e
|
|
${SCP_COMMAND} ccp.yml vagrant@"${ADMIN_IP}":~/
|
|
${SSH_COMMAND} "ccp -vvv --debug --config-file ~/ccp.yml fetch"
|
|
${SCP_COMMAND} -r ~/skel/* vagrant@"${ADMIN_IP}":/tmp/ccp-repos/rally/service/files
|
|
set +e
|
|
# Run CCP deployment and OpenStack tests:
|
|
deploy_ccp
|
|
DEPLOY_STATUS=$?
|
|
#set tag dependent from test result
|
|
if [[ "${DEPLOY_STATUS}" != 0 ]]; then
|
|
echo "Deployment failed! Check diagnostic snapshot."
|
|
${SCP_COMMAND} vagrant@"${ADMIN_IP}":~/tmp/ccp-diag/*.tar.gz .
|
|
scp -i ~/.ssh/jenkins_storage *.tar.gz share@share01-scc.ng.mirantis.net:/srv/static/share/tests/diagnostic/
|
|
exit 1
|
|
fi
|
|
|
|
sshpass -p vagrant ssh -o StrictHostKeyChecking=no vagrant@"${ADMIN_IP}" "echo ${DOCKER_REGISTRY_IP} ${DOCKER_REGISTRY_HOST} |sudo tee -a /etc/hosts"
|
|
TEMPEST_NAME=`sshpass -p vagrant ssh -o StrictHostKeyChecking=no vagrant@"${ADMIN_IP}" "ccp -vvv --debug --config-file ~/ccp.yml action run tempest -f value -c name"`
|
|
|
|
stop = 0
|
|
until [ ${stop} -eq 1 ]; do
|
|
test_status=`${SSH_COMMAND} ccp -vvv --debug action status ${TEMPEST_NAME} -f value -c status`
|
|
if [ "${test_status}" == "fail" ]; then
|
|
stop=1
|
|
DOCKER_TAG="${IMAGES_TAG}-unstable"
|
|
elif [ "${test_status}" == "ok" ]; then
|
|
stop=1
|
|
DOCKER_TAG="${IMAGES_TAG}"
|
|
else
|
|
sleep 60
|
|
fi
|
|
done
|
|
|
|
|
|
${SSH_COMMAND} kubectl -n ccp logs ${TEMPEST_NAME} | grep -A 9 Totals
|
|
${SSH_COMMAND} kubectl -n ccp logs ${TEMPEST_NAME} -p | grep -A 9 Totals
|
|
wget http://share01-scc.ng.mirantis.net/tests/tests/result-${VERSION}.xml
|
|
set -e
|
|
|
|
IMG=`sshpass -p vagrant ssh -o StrictHostKeyChecking=no vagrant@${ADMIN_IP} docker images --format "{{.Repository}}" | awk -F'/' -v search=/${IMAGES_NAMESPACE}/ '$0 ~ search {print $3}'`
|
|
|
|
# we need docker config file to authentication in remote repository
|
|
sshpass -p vagrant ssh -o StrictHostKeyChecking=no vagrant@"${ADMIN_IP}" mkdir -p /home/vagrant/.docker/
|
|
sshpass -p vagrant scp -o StrictHostKeyChecking=no /home/jenkins/.docker/config.json vagrant@"${ADMIN_IP}":~/.docker/
|
|
|
|
for f in ${IMG}; do
|
|
sshpass -p vagrant ssh -o StrictHostKeyChecking=no vagrant@"${ADMIN_IP}" \
|
|
"docker tag ${REGISTRY_IP}:${REGISTRY_PORT}/${IMAGES_NAMESPACE}/$f:latest ${DOCKER_REGISTRY}/${REGISTRY_NAMESPACE}/${f}:${DOCKER_TAG} && docker push ${DOCKER_REGISTRY}/${REGISTRY_NAMESPACE}/${f}:${DOCKER_TAG}"
|
|
if [ "${IMAGES_TAG}" == "ocata" ]; then
|
|
sshpass -p vagrant ssh -o StrictHostKeyChecking=no vagrant@"${ADMIN_IP}" \
|
|
"docker tag ${REGISTRY_IP}:${REGISTRY_PORT}/${IMAGES_NAMESPACE}/${f}:latest ${DOCKER_REGISTRY}/${REGISTRY_NAMESPACE}/${f}:latest \
|
|
&& docker push ${DOCKER_REGISTRY}/${REGISTRY_NAMESPACE}/${f}:latest"
|
|
fi
|
|
done
|
|
else
|
|
set +e
|
|
# Run CCP deployment and OpenStack tests:
|
|
deploy_ccp
|
|
DEPLOY_STATUS=$?
|
|
echo "Deploy status: ${DEPLOY_STATUS}"
|
|
set -e
|
|
fi
|
|
|
|
# Revert to fresh to decrease image size
|
|
dos.py revert "${FUEL_DEVOPS_ENV_NAME}" "${FUEL_DEVOPS_SNAPSHOT_NAME}"
|
|
|
|
# Clean-up (snapshot should remain for next jobs):
|
|
dos.py destroy "${FUEL_DEVOPS_ENV_NAME}"
|