From 10e776642a16b2584be88e5be8740f05535d7d06 Mon Sep 17 00:00:00 2001 From: "carey.xu" Date: Mon, 10 Aug 2015 23:02:31 -0400 Subject: Add deploy scripts for compass JIRA: COMPASS-11 Change-Id: Id588912c73b424228b6f01cd47fd282d040f7b8f Signed-off-by: carey.xu --- ci/deploy.sh | 9 ++ ci/launch.sh | 65 ++++++++++++++ ci/log.sh | 22 +++++ deploy/compass_vm.sh | 100 +++++++++++++++++++++ deploy/conf/baremetal.conf | 20 +++++ deploy/conf/base.conf | 78 +++++++++++++++++ deploy/conf/cluster.conf | 20 +++++ deploy/conf/five.conf | 19 ++++ deploy/deploy_host.sh | 41 +++++++++ deploy/host_baremetal.sh | 14 +++ deploy/host_vm.sh | 61 +++++++++++++ deploy/mac_generator.sh | 23 +++++ deploy/network.sh | 70 +++++++++++++++ deploy/prepare.sh | 35 ++++++++ deploy/remote_excute.exp | 35 ++++++++ deploy/status_callback.py | 174 +++++++++++++++++++++++++++++++++++++ deploy/template/network/bridge.xml | 5 ++ deploy/template/network/nat.xml | 10 +++ deploy/template/vm/compass.xml | 64 ++++++++++++++ deploy/template/vm/host.xml | 67 ++++++++++++++ 20 files changed, 932 insertions(+) create mode 100755 ci/deploy.sh create mode 100755 ci/launch.sh create mode 100755 ci/log.sh create mode 100644 deploy/compass_vm.sh create mode 100644 deploy/conf/baremetal.conf create mode 100644 deploy/conf/base.conf create mode 100644 deploy/conf/cluster.conf create mode 100644 deploy/conf/five.conf create mode 100644 deploy/deploy_host.sh create mode 100644 deploy/host_baremetal.sh create mode 100644 deploy/host_vm.sh create mode 100755 deploy/mac_generator.sh create mode 100755 deploy/network.sh create mode 100755 deploy/prepare.sh create mode 100755 deploy/remote_excute.exp create mode 100755 deploy/status_callback.py create mode 100644 deploy/template/network/bridge.xml create mode 100644 deploy/template/network/nat.xml create mode 100644 deploy/template/vm/compass.xml create mode 100644 deploy/template/vm/host.xml diff --git a/ci/deploy.sh b/ci/deploy.sh new file mode 100755 index 00000000..197bf63b --- /dev/null +++ b/ci/deploy.sh @@ -0,0 +1,9 @@ +#set -x +COMPASS_DIR=`cd ${BASH_SOURCE[0]%/*}/../;pwd` +export COMPASS_DIR + +apt-get install screen +screen -ls |grep deploy|awk -F. '{print $1}'|xargs kill -9 +screen -wipe +#screen -dmSL deploy bash $COMPASS_DIR/ci/launch.sh $* +$COMPASS_DIR/ci/launch.sh $* diff --git a/ci/launch.sh b/ci/launch.sh new file mode 100755 index 00000000..316b06f5 --- /dev/null +++ b/ci/launch.sh @@ -0,0 +1,65 @@ +#set -x +WORK_DIR=$COMPASS_DIR/ci/work + +if [[ $# -ge 1 ]];then + CONF_NAME=$1 +else + CONF_NAME=cluster +fi + +source ${COMPASS_DIR}/ci/log.sh +source ${COMPASS_DIR}/deploy/conf/${CONF_NAME}.conf +source ${COMPASS_DIR}/deploy/prepare.sh +source ${COMPASS_DIR}/deploy/network.sh + +if [[ ! -z $VIRT_NUMBER ]];then + source ${COMPASS_DIR}/deploy/host_vm.sh +else + source ${COMPASS_DIR}/deploy/host_baremetal.sh +fi + +source ${COMPASS_DIR}/deploy/compass_vm.sh +source ${COMPASS_DIR}/deploy/deploy_host.sh + +######################### main process + +if ! prepare_env;then + echo "prepare_env failed" + exit 1 +fi + +log_info "########## get host mac begin #############" +machines=`get_host_macs` +if [[ -z $machines ]];then + log_error "get_host_macs failed" + exit 1 +fi + +log_info "deploy host macs: $machines" +export machines + +log_info "########## set up network begin #############" +if ! create_nets;then + log_error "create_nets failed" + exit 1 +fi + +if ! launch_compass;then + log_error "launch_compass failed" + exit 1 +fi +if [[ ! -z $VIRT_NUMBER ]];then + if ! launch_host_vms;then + log_error "launch_host_vms failed" + exit 1 + fi +fi +if ! deploy_host;then + #tear_down_machines + #tear_down_compass + exit 1 +else + #tear_down_machines + #tear_down_compass + exit 0 +fi diff --git a/ci/log.sh b/ci/log.sh new file mode 100755 index 00000000..f54fdca5 --- /dev/null +++ b/ci/log.sh @@ -0,0 +1,22 @@ +#!/bin/bash +reset=`tput sgr0` +red=`tput setaf 1` +green=`tput setaf 2` +yellow=`tput setaf 3` + +function log_info() { + echo -e "${green}$*${reset}" +} + +function log_warn() { + echo -e "${yellow}$*${reset}" +} + +function log_error() { + echo -e "${red}$*${reset}" +} + +function log_progress() { + echo -en "${yellow}$*\r${reset}" +} + diff --git a/deploy/compass_vm.sh b/deploy/compass_vm.sh new file mode 100644 index 00000000..fb7e6ab9 --- /dev/null +++ b/deploy/compass_vm.sh @@ -0,0 +1,100 @@ +compass_vm_dir=$WORK_DIR/vm/compass +rsa_file=$compass_vm_dir/boot.rsa +ssh_args="-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i $rsa_file" +function tear_down_compass() { + sudo virsh destroy compass > /dev/null 2>&1 + sudo virsh undefine compass > /dev/null 2>&1 + + sudo umount $compass_vm_dir/old > /dev/null 2>&1 + sudo umount $compass_vm_dir/new > /dev/null 2>&1 + + sudo rm -rf $compass_vm_dir + log_info "tear_down_compass success!!!" +} + +function install_compass_core() { + local inventory_file=$compass_vm_dir/inventory.file + log_info "install_compass_core enter" + sed -i "s/mgmt_next_ip:.*/mgmt_next_ip: ${COMPASS_SERVER}/g" $WORK_DIR/installer/compass-install/install/group_vars/all + echo "compass_nodocker ansible_ssh_host=$MGMT_IP ansible_ssh_port=22" > $inventory_file + PYTHONUNBUFFERED=1 ANSIBLE_FORCE_COLOR=true ANSIBLE_HOST_KEY_CHECKING=false ANSIBLE_SSH_ARGS='-o UserKnownHostsFile=/dev/null -o ControlMaster=auto -o ControlPersist=60s' ansible-playbook -e pipeline=true --private-key=$rsa_file --user=root --connection=ssh --inventory-file=$inventory_file $WORK_DIR/installer/compass-install/install/compass_nodocker.yml + exit_status=$? + rm $inventory_file + log_info "install_compass_core exit" + if [[ $exit_status != 0 ]];then + /bin/false + fi +} + +function wait_ok() { + log_info "wait_compass_ok enter" + retry=0 + until timeout 1s ssh $ssh_args root@$MGMT_IP "exit" 2>/dev/null + do + log_progress "os install time used: $((retry*100/$1))%" + sleep 1 + let retry+=1 + if [[ $retry -ge $1 ]];then + log_error "os install time out" + exit 1 + fi + done + + log_warn "os install time used: 100%" + log_info "wait_compass_ok exit" +} + +function launch_compass() { + local old_mnt=$compass_vm_dir/old + local new_mnt=$compass_vm_dir/new + local old_iso=$WORK_DIR/iso/centos.iso + local new_iso=$compass_vm_dir/centos.iso + + log_info "launch_compass enter" + tear_down_compass + + set -e + mkdir -p $compass_vm_dir $old_mnt + sudo mount -o loop $old_iso $old_mnt + cd $old_mnt;find .|cpio -pd $new_mnt;cd - + + sudo umount $old_mnt + + chmod 755 -R $new_mnt + sed -i -e "s/REPLACE_MGMT_IP/$MGMT_IP/g" -e "s/REPLACE_MGMT_NETMASK/$MGMT_MASK/g" -e "s/REPLACE_INSTALL_IP/$COMPASS_SERVER/g" -e "s/REPLACE_INSTALL_NETMASK/$INSTALL_MASK/g" -e "s/REPLACE_GW/$MGMT_GW/g" $new_mnt/isolinux/isolinux.cfg + + ssh-keygen -f $new_mnt/bootstrap/boot.rsa -t rsa -N '' + cp $new_mnt/bootstrap/boot.rsa $rsa_file + + rm -rf $new_mnt/.rr_moved $new_mnt/rr_moved + sudo mkisofs -quiet -r -J -R -b isolinux/isolinux.bin -no-emul-boot -boot-load-size 4 -boot-info-table -hide-rr-moved -x "lost+found:" -o $new_iso $new_mnt + + rm -rf $old_mnt $new_mnt + qemu-img create -f qcow2 $compass_vm_dir/disk.img 100G + + # create vm xml + sed -e "s/REPLACE_MEM/$COMPASS_VIRT_MEM/g" \ + -e "s/REPLACE_CPU/$COMPASS_VIRT_CPUS/g" \ + -e "s#REPLACE_IMAGE#$compass_vm_dir/disk.img#g" \ + -e "s#REPLACE_ISO#$compass_vm_dir/centos.iso#g" \ + -e "s/REPLACE_NET_MGMT/mgmt/g" \ + -e "s/REPLACE_BRIDGE_INSTALL/br_install/g" \ + $COMPASS_DIR/deploy/template/vm/compass.xml \ + > $WORK_DIR/vm/compass/libvirt.xml + + sudo virsh define $compass_vm_dir/libvirt.xml + sudo virsh start compass + + if ! wait_ok 300;then + log_error "install os timeout" + exit 1 + fi + + if ! install_compass_core;then + log_error "install compass core failed" + exit 1 + fi + + set +e + log_info "launch_compass exit" +} diff --git a/deploy/conf/baremetal.conf b/deploy/conf/baremetal.conf new file mode 100644 index 00000000..bcf743eb --- /dev/null +++ b/deploy/conf/baremetal.conf @@ -0,0 +1,20 @@ +export VIRT_CPUS=4 +export HOST_MACS="'64:3e:8c:4c:6d:a3' '64:3e:8c:4c:6d:37' '64:3e:8c:4c:6c:d7' '64:3e:8c:4c:6b:7b' '64:3e:8c:4c:68:2b'" +export VIRT_MEM=16384 +export VIRT_DISK=30G +export 'ADAPTER_OS_PATTERN=(?i)ubuntu-14\.04.*' +#export 'ADAPTER_OS_PATTERN=(?i)centos-7\.1.*' +export ADAPTER_NAME="openstack_juno" +export ADAPTER_TARGET_SYSTEM_PATTERN="^openstack$" +export ADAPTER_FLAVOR_PATTERN="HA-ansible-multinodes" +export HOSTNAMES="host1,host2,host3,host4,host5" +export HOST_ROLES="host1=controller,ha;host2=controller,ha;host3=controller,ha;host4=compute;host5=compute" +export DEFAULT_ROLES="" +export SWITCH_IPS="192.168.124.2" +export SWITCH_CREDENTIAL="version=2c,community=public" +export DEPLOYMENT_TIMEOUT="150" +export POLL_SWITCHES_FLAG="nopoll_switches" +export DASHBOARD_URL="" +export REGTEST_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +source ${REGTEST_DIR}/base.conf +export VIP="10.1.0.222" diff --git a/deploy/conf/base.conf b/deploy/conf/base.conf new file mode 100644 index 00000000..be346ddf --- /dev/null +++ b/deploy/conf/base.conf @@ -0,0 +1,78 @@ +export ISO_URL=http://192.168.127.11:9999/xh/work/build/work/compass.iso +export INSTALL_IP=${INSTALL_IP:-10.1.0.12} +export INSTALL_MASK=${INSTALL_MASK:-255.255.255.0} +export INSTALL_GW=${INSTALL_GW:-10.1.0.1} +export INSTALL_IP_START=${INSTALL_IP_START:-10.1.0.1} +export INSTALL_IP_END=${INSTALL_IP_END:-10.1.0.254} +export MGMT_IP=${MGMT_IP:-192.168.200.2} +export MGMT_MASK=${MAGMT_MASK:-255.255.252.0} +export MGMT_GW=${MAGMT_GW:-192.168.200.1} +export MGMT_IP_START=${MGMT_IP_START:-192.168.200.3} +export MGMT_IP_END=${MGMT_IP_END:-192.168.200.254} +export OM_NIC=${OM_NIC:-eth3} +export OM_IP=${OM_IP:-192.168.127.11/22} +export OM_GW=${OM_GW:-192.168.124.1} +export COMPASS_VIRT_CPUS=4 +export COMPASS_VIRT_MEM=4096 +export COMPASS_SERVER=$INSTALL_IP +export COMPASS_SERVER_URL="http://$COMPASS_SERVER/api" +export COMPASS_USER_EMAIL="admin@huawei.com" +export COMPASS_USER_PASSWORD="admin" +export CLUSTER_NAME="opnfv2" +export LANGUAGE="EN" +export TIMEZONE="America/Los_Angeles" +export NTP_SERVER="$COMPASS_SERVER" +export NAMESERVERS="$COMPASS_SERVER" +export DOMAIN="ods.com" +export PARTITIONS="/=70%,/home=5%,/tmp=5%,/var=20%" +export SUBNETS="10.1.0.0/24,172.16.2.0/24,172.16.3.0/24,172.16.4.0/24" +export MANAGEMENT_IP_START=${MANAGEMENT_IP_START:-'10.1.0.50'} +export TENANT_IP_START=${TENANT_IP_START:-'172.16.2.50'} +export PUBLIC_IP_START=${PUBLIC_IP_START:-'172.16.3.50'} +export STORAGE_IP_START=${STORAGE_IP_START:-'172.16.4.50'} +export MANAGEMENT_INTERFACE=${MANAGEMENT_INTERFACE:-eth0} +export TENANT_INTERFACE=${TENANT_INTERFACE:-eth1} +export STORAGE_INTERFACE=${STORAGE_INTERFACE:-eth3} +export PUBLIC_INTERFACE=${PUBLIC_INTERFACE:-eth2} + + +function next_ip { + ip_addr=$1 + ip_base="$(echo $ip_addr | cut -d. -f'1 2 3')" + ip_last="$(echo $ip_addr | cut -d. -f4)" + let ip_last_next=$ip_last+1 + echo "${ip_base}.${ip_last_next}" +} + +if [ -z "$HOST_NETWORKS" ]; then + IFS=, read -a HOSTNAME_LIST <<< "$HOSTNAMES" + MANAGE_IP=${MANAGEMENT_IP_START} + TENANT_IP=${TENANT_IP_START} + PUBLIC_IP=${PUBLIC_IP_START} + STORAGE_IP=${STORAGE_IP_START} + for HOSTNAME in ${HOSTNAME_LIST[@]}; do + if [ -z "$HOST_NETWORKS" ]; then + HOST_NETWORKS="${HOSTNAME}:${MANAGEMENT_INTERFACE}=${MANAGE_IP}|is_mgmt,${TENANT_INTERFACE}=${TENANT_IP},${PUBLIC_INTERFACE}=${PUBLIC_IP}|is_promiscuous,${STORAGE_INTERFACE}=${STORAGE_IP}" + else + HOST_NETWORKS="${HOST_NETWORKS};${HOSTNAME}:${MANAGEMENT_INTERFACE}=${MANAGE_IP}|is_mgmt,${TENANT_INTERFACE}=${TENANT_IP},${PUBLIC_INTERFACE}=${PUBLIC_IP}|is_promiscuous,${STORAGE_INTERFACE}=${STORAGE_IP}" + fi + MANAGE_IP=$(next_ip ${MANAGE_IP}) + TENANT_IP=$(next_ip ${TENANT_IP}) + PUBLIC_IP=$(next_ip ${PUBLIC_IP}) + STORAGE_IP=$(next_ip ${STORAGE_IP}) + done + export HOST_NETWORKS +fi + +export NETWORK_MAPPING=${NETWORK_MAPPING:-"management=${MANAGEMENT_INTERFACE},tenant=${TENANT_INTERFACE},storage=${STORAGE_INTERFACE},external=${PUBLIC_INTERFACE}"} + +export PROXY="" +export IGNORE_PROXY="" +export SEARCH_PATH="ods.com" +export GATEWAY="10.1.0.1" +export SERVER_CREDENTIAL="root=root" +export LOCAL_REPO_URL="" +export OS_CONFIG_FILENAME="" +export SERVICE_CREDENTIALS="image:service=service,compute:service=service,dashboard:service=service,identity:service=service,metering:service=service,rabbitmq:service=service,volume:service=service,mysql:service=service" +export CONSOLE_CREDENTIALS="admin:console=console,compute:console=console,dashboard:console=console,image:console=console,metering:console=console,network:console=console,object-store:console=console,volume:console=console" +export PACKAGE_CONFIG_FILENAME="" diff --git a/deploy/conf/cluster.conf b/deploy/conf/cluster.conf new file mode 100644 index 00000000..ad797f9b --- /dev/null +++ b/deploy/conf/cluster.conf @@ -0,0 +1,20 @@ +export VIRT_NUMBER=5 +export VIRT_CPUS=4 +export VIRT_MEM=16384 +export VIRT_DISK=30G +export 'ADAPTER_OS_PATTERN=(?i)ubuntu-14\.04.*' +#export 'ADAPTER_OS_PATTERN=(?i)centos-7\.1.*' +export ADAPTER_NAME="openstack_juno" +export ADAPTER_TARGET_SYSTEM_PATTERN="^openstack$" +export ADAPTER_FLAVOR_PATTERN="HA-ansible-multinodes" +export HOSTNAMES="host1,host2,host3,host4,host5" +export HOST_ROLES="host1=controller,ha;host2=controller,ha;host3=controller,ha;host4=compute;host5=compute" +export DEFAULT_ROLES="" +export SWITCH_IPS="1.1.1.1" +export SWITCH_CREDENTIAL="version=2c,community=public" +export DEPLOYMENT_TIMEOUT="150" +export POLL_SWITCHES_FLAG="nopoll_switches" +export DASHBOARD_URL="" +export REGTEST_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +source ${REGTEST_DIR}/base.conf +export VIP="10.1.0.222" diff --git a/deploy/conf/five.conf b/deploy/conf/five.conf new file mode 100644 index 00000000..dec9eb7d --- /dev/null +++ b/deploy/conf/five.conf @@ -0,0 +1,19 @@ +export VIRT_NUMBER=5 +export VIRT_CPUS=4 +export VIRT_MEM=16384 +export VIRT_DISK=30G +export 'ADAPTER_OS_PATTERN=(?i)ubuntu-14\.04.*' +#export 'ADAPTER_OS_PATTERN=(?i)centos-7\.1.*' +export ADAPTER_NAME="openstack_juno" +export ADAPTER_TARGET_SYSTEM_PATTERN="^openstack$" +export ADAPTER_FLAVOR_PATTERN="single-controller" +export HOSTNAMES="host1,host2,host3,host4,host5" +export HOST_ROLES="host1=controller,network;host2=compute,storage;host3=compute,storage;host4=compute,storage;host5=compute,storage" +export DEFAULT_ROLES="" +export SWITCH_IPS="1.1.1.1" +export SWITCH_CREDENTIAL="version=2c,community=public" +export DEPLOYMENT_TIMEOUT="150" +export POLL_SWITCHES_FLAG="nopoll_switches" +export DASHBOARD_URL="" +export REGTEST_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +source ${REGTEST_DIR}/base.conf diff --git a/deploy/deploy_host.sh b/deploy/deploy_host.sh new file mode 100644 index 00000000..f95f2594 --- /dev/null +++ b/deploy/deploy_host.sh @@ -0,0 +1,41 @@ +function deploy_host(){ + cd $WORK_DIR/installer/compass-core + source $WORK_DIR/venv/bin/activate + if pip --help | grep -q trusted; then + pip install -i http://pypi.douban.com/simple -e . --trusted-host pypi.douban.com + else + pip install -i http://pypi.douban.com/simple -e . + fi + + sudo mkdir -p /var/log/compass + sudo chown -R 777 /var/log/compass + + sudo mkdir -p /etc/compass + sudo cp -rf conf/setting /etc/compass/. + + cp bin/switch_virtualenv.py.template bin/switch_virtualenv.py + sed -i "s|\$PythonHome|$VIRTUAL_ENV|g" bin/switch_virtualenv.py + ssh $ssh_args root@${COMPASS_SERVER} mkdir -p /opt/compass/bin/ansible_callbacks + scp $ssh_args -r ${COMPASS_DIR}/deploy/status_callback.py root@${COMPASS_SERVER}:/opt/compass/bin/ansible_callbacks/status_callback.py + + reboot_hosts + + bin/client.py --logfile= --loglevel=debug --logdir= --compass_server="${COMPASS_SERVER_URL}" \ + --compass_user_email="${COMPASS_USER_EMAIL}" --compass_user_password="${COMPASS_USER_PASSWORD}" \ + --cluster_name="${CLUSTER_NAME}" --language="${LANGUAGE}" --timezone="${TIMEZONE}" \ + --hostnames="${HOSTNAMES}" --partitions="${PARTITIONS}" --subnets="${SUBNETS}" \ + --adapter_os_pattern="${ADAPTER_OS_PATTERN}" --adapter_name="${ADAPTER_NAME}" \ + --adapter_target_system_pattern="${ADAPTER_TARGET_SYSTEM_PATTERN}" \ + --adapter_flavor_pattern="${ADAPTER_FLAVOR_PATTERN}" \ + --http_proxy="${PROXY}" --https_proxy="${PROXY}" --no_proxy="${IGNORE_PROXY}" \ + --ntp_server="${NTP_SERVER}" --dns_servers="${NAMESERVERS}" --domain="${DOMAIN}" \ + --search_path="${SEARCH_PATH}" --default_gateway="${GATEWAY}" \ + --server_credential="${SERVER_CREDENTIAL}" --local_repo_url="${LOCAL_REPO_URL}" \ + --os_config_json_file="${OS_CONFIG_FILENAME}" --service_credentials="${SERVICE_CREDENTIALS}" \ + --console_credentials="${CONSOLE_CREDENTIALS}" --host_networks="${HOST_NETWORKS}" \ + --network_mapping="${NETWORK_MAPPING}" --package_config_json_file="${PACKAGE_CONFIG_FILENAME}" \ + --host_roles="${HOST_ROLES}" --default_roles="${DEFAULT_ROLES}" --switch_ips="${SWITCH_IPS}" \ + --machines=${machines//\'} --switch_credential="${SWITCH_CREDENTIAL}" \ + --deployment_timeout="${DEPLOYMENT_TIMEOUT}" --${POLL_SWITCHES_FLAG} --dashboard_url="${DASHBOARD_URL}" \ + --cluster_vip="${VIP}" +} diff --git a/deploy/host_baremetal.sh b/deploy/host_baremetal.sh new file mode 100644 index 00000000..a543528f --- /dev/null +++ b/deploy/host_baremetal.sh @@ -0,0 +1,14 @@ +function reboot_hosts() { + cmd='for i in {14..18}; do /dev/shm/smm/usr/bin/smmset -l blade$i -d bootoption -v 1 0; echo Y | /dev/shm/smm/usr/bin/smmset -l blade$i -d frucontrol -v 0; done' + /usr/bin/expect ${COMPASS_DIR}/deploy/remote_excute.exp ${SWITCH_IPS} 'root' 'Admin@7*24' "$cmd" +} + +function get_host_macs() { + local config_file=$WORK_DIR/installer/compass-install/install/group_vars/all + local machines=`echo $HOST_MACS|sed 's/ /,/g'` + + echo "test: true" >> $config_file + echo "pxe_boot_macs: [${machines}]" >> $config_file + + echo $machines +} diff --git a/deploy/host_vm.sh b/deploy/host_vm.sh new file mode 100644 index 00000000..0754b1f4 --- /dev/null +++ b/deploy/host_vm.sh @@ -0,0 +1,61 @@ +host_vm_dir=$WORK_DIR/vm +function tear_down_machines() { + for i in $HOSTNAMES; do + sudo virsh destroy $i + sudo virsh undefine $i + rm -rf $host_vm_dir/$i + done +} + +function reboot_hosts() { + log_warn "reboot_hosts do nothing" +} + +function launch_host_vms() { + old_ifs=$IFS + IFS=, + tear_down_machines + #function_bod + mac_array=($machines) + log_info "bringing up pxe boot vms" + i=0 + for host in $HOSTNAMES; do + log_info "creating vm disk for instance $host" + vm_dir=$host_vm_dir/$host + mkdir -p $vm_dir + sudo qemu-img create -f raw $vm_dir/disk.img ${VIRT_DISK} + # create vm xml + sed -e "s/REPLACE_MEM/$VIRT_MEM/g" \ + -e "s/REPLACE_CPU/$VIRT_CPUS/g" \ + -e "s/REPLACE_NAME/$host/g" \ + -e "s#REPLACE_IMAGE#$vm_dir/disk.img#g" \ + -e "s/REPLACE_BOOT_MAC/${mac_array[i]}/g" \ + -e "s/REPLACE_BRIDGE_MGMT/br_install/g" \ + -e "s/REPLACE_BRIDGE_TENANT/br_install/g" \ + -e "s/REPLACE_BRIDGE_PUBLIC/br_install/g" \ + -e "s/REPLACE_BRIDGE_STORAGE/br_install/g" \ + $COMPASS_DIR/deploy/template/vm/host.xml\ + > $vm_dir/libvirt.xml + + sudo virsh define $vm_dir/libvirt.xml + sudo virsh start $host + let i=i+1 + done + IFS=$old_ifs +} + +function get_host_macs() { + local config_file=$WORK_DIR/installer/compass-install/install/group_vars/all + local mac_generator=${COMPASS_DIR}/deploy/mac_generator.sh + local machines= + + chmod +x $mac_generator + mac_array=`$mac_generator $VIRT_NUMBER` + machines=`echo $mac_array|sed 's/ /,/g'` + + echo "test: true" >> $config_file + echo "pxe_boot_macs: [${machines}]" >> $config_file + + echo $machines +} + diff --git a/deploy/mac_generator.sh b/deploy/mac_generator.sh new file mode 100755 index 00000000..8dee3753 --- /dev/null +++ b/deploy/mac_generator.sh @@ -0,0 +1,23 @@ +#!/bin/bash +function mac_address_part() { + hex_number=$(printf '%02x' $RANDOM) + number_length=${#hex_number} + number_start=$(expr $number_length - 2) + echo ${hex_number:$number_start:2} +} + +function mac_address() { + echo "'00:00:$(mac_address_part):$(mac_address_part):$(mac_address_part):$(mac_address_part)'" +} + +machines='' +for i in `seq $1`; do + mac=$(mac_address) + + if [[ -z $machines ]]; then + machines="${mac}" + else + machines="${machines} ${mac}" + fi +done +echo ${machines} diff --git a/deploy/network.sh b/deploy/network.sh new file mode 100755 index 00000000..851a685a --- /dev/null +++ b/deploy/network.sh @@ -0,0 +1,70 @@ +function destroy_nets() { + sudo virsh net-destroy mgmt > /dev/null 2>&1 + sudo virsh net-undefine mgmt > /dev/null 2>&1 + + sudo virsh net-destroy install > /dev/null 2>&1 + sudo virsh net-undefine install > /dev/null 2>&1 + rm -rf $COMPASS_DIR/deploy/work/network/*.xml +} + +function setup_om_bridge() { + local device=$1 + local gw=$2 + ip link set br_install down + ip addr flush $device + brctl delbr br_install + + brctl addbr br_install + brctl addif br_install $device + ip link set br_install up + + shift;shift + for ip in $*;do + ip addr add $ip dev br_install + done + + route add default gw $gw +} + +function setup_om_nat() { + # create install network + sed -e "s/REPLACE_BRIDGE/br_install/g" \ + -e "s/REPLACE_NAME/install/g" \ + -e "s/REPLACE_GATEWAY/$INSTALL_GW/g" \ + -e "s/REPLACE_MASK/$INSTALL_MASK/g" \ + -e "s/REPLACE_START/$INSTALL_IP_START/g" \ + -e "s/REPLACE_END/$INSTALL_IP_END/g" \ + $COMPASS_DIR/deploy/template/network/nat.xml \ + > $WORK_DIR/network/install.xml + + sudo virsh net-define $WORK_DIR/network/install.xml + sudo virsh net-start install +} + +function create_nets() { + destroy_nets + + # create mgmt network + sed -e "s/REPLACE_BRIDGE/br_mgmt/g" \ + -e "s/REPLACE_NAME/mgmt/g" \ + -e "s/REPLACE_GATEWAY/$MGMT_GW/g" \ + -e "s/REPLACE_MASK/$MGMT_MASK/g" \ + -e "s/REPLACE_START/$MGMT_IP_START/g" \ + -e "s/REPLACE_END/$MGMT_IP_END/g" \ + $COMPASS_DIR/deploy/template/network/nat.xml \ + > $WORK_DIR/network/mgmt.xml + + sudo virsh net-define $WORK_DIR/network/mgmt.xml + sudo virsh net-start mgmt + + # create install network + if [[ ! -z $VIRT_NUMBER ]];then + setup_om_nat + else + mask=`echo $INSTALL_MASK | awk -F'.' '{print ($1*(2^24)+$2*(2^16)+$3*(2^8)+$4)}'` + mask_len=`echo "obase=2;${mask}"|bc|awk -F'0' '{print length($1)}'` + setup_om_bridge $OM_NIC $OM_GW $INSTALL_GW/$mask_len $OM_IP + fi + +} + diff --git a/deploy/prepare.sh b/deploy/prepare.sh new file mode 100755 index 00000000..1b0ded8c --- /dev/null +++ b/deploy/prepare.sh @@ -0,0 +1,35 @@ +function prepare_env() { + export PYTHONPATH=/usr/lib/python2.7/dist-packages:/usr/local/lib/python2.7/dist-packages + sudo apt-get update -y + sudo apt-get install mkisofs bc + sudo apt-get install git python-pip python-dev -y + sudo apt-get install libxslt-dev libxml2-dev libvirt-dev build-essential qemu-utils qemu-kvm libvirt-bin virtinst libmysqld-dev -y + sudo pip install --upgrade pip + sudo pip install --upgrade ansible + sudo pip install --upgrade virtualenv + sudo service libvirt-bin restart + + # prepare work dir + sudo rm -rf $WORK_DIR + mkdir -p $WORK_DIR + mkdir -p $WORK_DIR/installer + mkdir -p $WORK_DIR/vm + mkdir -p $WORK_DIR/network + mkdir -p $WORK_DIR/iso + mkdir -p $WORK_DIR/venv + + if [[ ! -f centos.iso ]];then + wget -O $WORK_DIR/iso/centos.iso $ISO_URL + fi + + # copy compass + mkdir -p $WORK_DIR/mnt + sudo mount -o loop $WORK_DIR/iso/centos.iso $WORK_DIR/mnt + cp -rf $WORK_DIR/mnt/compass/compass-core $WORK_DIR/installer/ + cp -rf $WORK_DIR/mnt/compass/compass-install $WORK_DIR/installer/ + sudo umount $WORK_DIR/mnt + rm -rf $WORK_DIR/mnt + + chmod 755 $WORK_DIR -R + virtualenv $WORK_DIR/venv +} diff --git a/deploy/remote_excute.exp b/deploy/remote_excute.exp new file mode 100755 index 00000000..ac901353 --- /dev/null +++ b/deploy/remote_excute.exp @@ -0,0 +1,35 @@ +#!/usr/bin/expect + +set addr [lindex $argv 0] +set user [lindex $argv 1] +set passwd [lindex $argv 2] +set command [lindex $argv 3] +set cmd_prompt "]#|~]?" + +eval spawn ssh $user@$addr +set timeout 60 + +expect { + -re ".*es.*o.*" + { + exp_send "yes\r" + exp_continue + } + + -re ".*sword:" { + exp_send "$passwd\r" + exp_continue + } + -re $cmd_prompt { + exp_send "$command\r" + } +} + +exec sleep 1 + +expect { + -re $cmd_prompt { + send "exit\r" + } +} +send "exit 1\r" diff --git a/deploy/status_callback.py b/deploy/status_callback.py new file mode 100755 index 00000000..86191322 --- /dev/null +++ b/deploy/status_callback.py @@ -0,0 +1,174 @@ +# (C) 2012, Michael DeHaan, + +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +import httplib +import json +import sys +import logging + +def task_error(host, data): + logging.info("task_error: host=%s,data=%s" % (host, data)) + + if type(data) == dict: + invocation = data.pop('invocation', {}) + + notify_host("localhost", host, "failed") + +class CallbackModule(object): + """ + logs playbook results, per host, in /var/log/ansible/hosts + """ + + def on_any(self, *args, **kwargs): + pass + + def runner_on_failed(self, host, res, ignore_errors=False): + task_error(host, res) + + def runner_on_ok(self, host, res): + pass + + def runner_on_skipped(self, host, item=None): + pass + + def runner_on_unreachable(self, host, res): + pass + + def runner_on_no_hosts(self): + pass + + def runner_on_async_poll(self, host, res, jid, clock): + pass + + def runner_on_async_ok(self, host, res, jid): + pass + + def runner_on_async_failed(self, host, res, jid): + task_error(host, res) + + def playbook_on_start(self): + pass + + def playbook_on_notify(self, host, handler): + pass + + def playbook_on_no_hosts_matched(self): + pass + + def playbook_on_no_hosts_remaining(self): + pass + + def playbook_on_task_start(self, name, is_conditional): + pass + + def playbook_on_vars_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None, default=None): + pass + + def playbook_on_setup(self): + pass + + def playbook_on_import_for_host(self, host, imported_file): + pass + + def playbook_on_not_import_for_host(self, host, missing_file): + pass + + def playbook_on_play_start(self, name): + pass + + def playbook_on_stats(self, stats): + logging.info("playbook_on_stats enter") + hosts = sorted(stats.processed.keys()) + host_vars = self.playbook.inventory.get_variables(hosts[0]) + cluster_name = host_vars['cluster_name'] + failures = False + unreachable = False + + for host in hosts: + summary = stats.summarize(host) + + if summary['failures'] > 0: + failures = True + if summary['unreachable'] > 0: + unreachable = True + + if failures or unreachable: + for host in hosts: + notify_host("localhost", host, "error") + return + + for host in hosts: + clusterhost_name = host + "." + cluster_name + notify_host("localhost", clusterhost_name, "succ") + + +def raise_for_status(resp): + if resp.status < 200 or resp.status > 300: + raise RuntimeError("%s, %s, %s" % (resp.status, resp.reason, resp.read())) + +def auth(conn): + credential = {} + credential['email'] = "admin@huawei.com" + credential['password'] = "admin" + url = "/api/users/token" + headers = {"Content-type": "application/json", + "Accept": "*/*"} + conn.request("POST", url, json.dumps(credential), headers) + resp = conn.getresponse() + + raise_for_status(resp) + return json.loads(resp.read())["token"] + +def notify_host(compass_host, host, status): + if status == "succ": + body = {"ready": True} + url = "/api/clusterhosts/%s/state_internal" % host + elif status == "error": + body = {"state": "ERROR"} + host = host.strip("host") + url = "/api/clusterhosts/%s/state" % host + else: + logging.error("notify_host: host %s with status %s is not supported" \ + % (host, status)) + return + + headers = {"Content-type": "application/json", + "Accept": "*/*"} + + conn = httplib.HTTPConnection(compass_host, 80) + token = auth(conn) + headers["X-Auth-Token"] = token + logging.info("host=%s,url=%s,body=%s,headers=%s" % (compass_host,url,json.dumps(body),headers)) + conn.request("POST", url, json.dumps(body), headers) + resp = conn.getresponse() + try: + raise_for_status(resp) + logging.info("notify host status success!!! status=%s, body=%s" % (resp.status, resp.read())) + except Exception as e: + logging.error("http request failed %s" % str(e)) + raise + finally: + conn.close() + +if __name__ == "__main__": + if len(sys.argv) != 3: + logging.error("params: host, status is need") + sys.exit(1) + + host = sys.argv[1] + status = sys.argv[2] + notify_host(host, status) diff --git a/deploy/template/network/bridge.xml b/deploy/template/network/bridge.xml new file mode 100644 index 00000000..0555a4e0 --- /dev/null +++ b/deploy/template/network/bridge.xml @@ -0,0 +1,5 @@ + + REPLACE_NAME + + + diff --git a/deploy/template/network/nat.xml b/deploy/template/network/nat.xml new file mode 100644 index 00000000..358fb50d --- /dev/null +++ b/deploy/template/network/nat.xml @@ -0,0 +1,10 @@ + + REPLACE_NAME + + + + + + diff --git a/deploy/template/vm/compass.xml b/deploy/template/vm/compass.xml new file mode 100644 index 00000000..918a9f21 --- /dev/null +++ b/deploy/template/vm/compass.xml @@ -0,0 +1,64 @@ + + compass + REPLACE_MEM + REPLACE_MEM + REPLACE_CPU + + hvm + + + + + + + + + + + + + + + destroy + restart + destroy + + /usr/bin/kvm-spice + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + diff --git a/deploy/template/vm/host.xml b/deploy/template/vm/host.xml new file mode 100644 index 00000000..b399e6ff --- /dev/null +++ b/deploy/template/vm/host.xml @@ -0,0 +1,67 @@ + + REPLACE_NAME + REPLACE_MEM + REPLACE_MEM + REPLACE_CPU + + hvm + + + + + + + + + + + destroy + restart + restart + + /usr/bin/kvm-spice + + + + + + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + + + + + + + + + +