Advertisement
Guest User

Untitled

a guest
Feb 5th, 2019
256
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 52.24 KB | None | 0 0
  1. #!/bin/bash
  2. #
  3. #
  4. #   Field PM Team - Please send your feedback/bugs to Gregory Charot - gcharot@redhat.com
  5. #
  6.  
  7. VERSION=2.6
  8.  
  9.  
  10. ######## PLEASE REVIEW ALL OPTIONS BELOW BEFORE RUNNING THE SCRIPT #########
  11.  
  12.  
  13. ##########################################################################
  14. #                                                                        #
  15. #                        Subscription management                         #
  16. #                                                                        #
  17. ##########################################################################
  18.  
  19.  
  20. # How do you want to register the systems ?
  21. # ACCEPTED values are "rhos-release" or "rhn"
  22. # PLEASE double check options below for each case.
  23.  
  24. SUB_TYPE="rhos-release"
  25.  
  26.  
  27. ### For rhos-release only!
  28.  
  29. RHOS_VERSION=14
  30.  
  31. ### For RHN only!
  32. # WARNING Test coverage of this feature is limited
  33. # The script will attach your employee subscription
  34.  
  35. # Your RHN login
  36. RHN_USERNAME="my-rhn-login"
  37. # Your RHN password - will be asked interactively if left empty
  38. RHN_PASSWD=""
  39. # RHEL Major Version
  40. RHEL_MAJ_VERSION="7"
  41. # RH-OSP major version
  42. OSP_MAJ_VERSION="10"
  43.  
  44.  
  45. ##########################################################################
  46. #                                                                        #
  47. #                          Environment Definitions                       #
  48. #                                                                        #
  49. ##########################################################################
  50.  
  51. ### IRONIC Driver
  52. # Accepted values are ssh|vbmc
  53. # pxe_ssh NOT supported starting OSP12
  54. # Default: vbmc
  55.  
  56. IRONIC_DRIVER="vbmc"
  57.  
  58. ### VM Memory (GB) and vCPU settings
  59.  
  60. # Undercloud
  61. UNDERC_MEM='20480'
  62. UNDERC_VCPU='8'
  63.  
  64. # Controllers - 12GB or greater is strongly adviced to avoid OOM errors during deployment
  65. CTRL_MEM='12288'
  66. CTRL_VCPU='4'
  67.  
  68. # Computes
  69. COMPT_MEM='6144'
  70. COMPT_VCPU='4'
  71.  
  72. # Ceph OSDs
  73. CEPH_MEM='4096'
  74. CEPH_VCPU='4'
  75. # Number of additional disks (OSDs/Journals) to attach to Ceph nodes. Default is 3 AND minimum is 1 - This value does NOT include the O.S disk which is handled automatically.
  76. CEPH_OSD_DISK=3
  77.  
  78. # Custom nodes
  79. CUST_MEM='4096'
  80. CUST_VCPU='2'
  81.  
  82. ### Overcloud node's list ###
  83.  
  84. # IMPORTANT #
  85.  
  86. # !!!!! You can add new nodes by adding them to the relevant type !!!
  87. # For example to add a 4th ceph node please set
  88. # CEPH_N="ceph01 ceph02 ceph03 ceph04"
  89.  
  90. CTRL_N="ctrl01 ctrl02 ctrl03"
  91. COMPT_N="compute01 compute02"
  92. CEPH_N="ceph01 ceph02 ceph03 ceph04"
  93. CUST_N="custom01 custom02"
  94.  
  95. # DO NOT change ALL_N variable !
  96. ALL_N="$CTRL_N $COMPT_N $CEPH_N $CUST_N"
  97.  
  98. ### IDM Configuration
  99.  
  100. # DEPLOY_IDM="yes" will deploy an IDM container on the hypervisor. IDM will be configured with FQDN: ipa.redhat.local. admin password is "redhat42" The undercloud will be configured to use this IDM.
  101. DEPLOY_IDM="yes"
  102. IDM_IMAGE="registry.access.redhat.com/rhel7/ipa-server"
  103. # IDM "external" bind IP, this IP must be exposed by the hypervisor. Default is to use a dummy IP (available only if IRONIC_DRIVER="vbmc")
  104. IDM_BIND_IP="192.168.1.20"
  105.  
  106. ### Overcloud's node ironic properties ###
  107.  
  108. # Defaults work for most cases
  109.  
  110. # Controller's nodes Ironic flavor
  111. CTRL_FLAVOR="control"
  112. # Controller's nodes scheduler hint - MUST NOT BE EMPTY - You can decide not to use in your THT.
  113. CTRL_SCHED="controller"
  114. # Controller's nodes extra properties. Add commas as needed
  115. CTRL_OTHER_PROP="boot_option:local"
  116.  
  117. # Compute's nodes Ironic flavor
  118. COMPT_FLAVOR="compute"
  119. # Compute's nodes scheduler hint - MUST NOT BE EMPTY - You can decide not to use it in your THT.
  120. COMPT_SCHED="compute"
  121. # Compute's nodes extra properties. Add commas as needed
  122. COMPT_OTHER_PROP="boot_option:local"
  123.  
  124. # Ceph's nodes Ironic flavor
  125. CEPH_FLAVOR="ceph-storage"
  126. # Ceph's nodes scheduler hint - MUST NOT BE EMPTY - You can decide not to use it in your THT.
  127. CEPH_SCHED="ceph"
  128. # Ceph's nodes extra properties. Add commas as needed
  129. CEPH_OTHER_PROP="boot_option:local"
  130.  
  131. # Custom's nodes Ironic flavor
  132. CUST_FLAVOR="networker"
  133. # Custom's nodes scheduler hint - MUST NOT BE EMPTY - You can decide not to use it in your THT.
  134. CUST_SCHED="networker"
  135. # Custom's nodes extra properties. Add commas as needed
  136. CUST_OTHER_PROP="boot_option:local"
  137.  
  138. ### Misc options
  139.  
  140. LIBVIRT_D="/var/lib/libvirt/"
  141. RHEL_IMAGE_U="http://10.12.50.1/pub/rhel-7-x86_64-latest.qcow2"
  142.  
  143. # You can add new packages to the hypervisor or undercloud system.
  144. PKG_HYPERVISOR="screen wget libvirt qemu-kvm virt-manager virt-install libguestfs-tools libguestfs-xfs xorg-x11-apps xauth virt-viewer xorg-x11-fonts-* net-tools ntpdate mlocate sshpass squid python-virtualbmc ipmitool python-setuptools"
  145. PKG_UNDERCLOUD="screen wget mlocate facter python-tripleoclient libvirt libguestfs-tools openstack-utils sshpass crudini ceph-ansible vim vim"
  146.  
  147. ### Passwords: undercloud and overcloud images ROOT PASSWORD are set to "redhat"
  148.  
  149. ##########################################################################
  150. #                                                                        #
  151. #                               Miscellaneous                            #
  152. #                                                                        #
  153. ##########################################################################
  154.  
  155. ### Ensure $TERM is defined.
  156. if [ "$TERM" = "dumb" ]; then export TERM="xterm-256color"; fi
  157.  
  158. ### Fancy colors
  159. RED=$(tput setaf 1)
  160. GREEN=$(tput setaf 2)
  161. NORMAL=$(tput sgr0)
  162.  
  163.  
  164. WHO_I_AM="$0"
  165.  
  166.  
  167. ##########################################################################
  168. #                                                                        #
  169. #                          Common Functions                              #
  170. #                                                                        #
  171. ##########################################################################
  172.  
  173.  
  174. #
  175. #  Print info message to stderr
  176. #
  177. function echoinfo() {
  178.   printf "${GREEN}INFO:${NORMAL} %s\n" "$*" >&2;
  179. }
  180.  
  181. #
  182. #  Print error message to stderr
  183. #
  184. function echoerr() {
  185.   printf "${RED}ERROR:${NORMAL} %s\n" "$*" >&2;
  186. }
  187.  
  188.  
  189. #
  190. #  Print exit message & exit 1
  191. #
  192. function exit_on_err()
  193. {
  194.   echoerr "Failed to deploy - Please check the output, fix the error and restart the script"
  195.   exit 1
  196. }
  197.  
  198. #
  199. # Help function
  200. #
  201.  
  202. function help() {
  203.   >&2 echo "Usage : osp-lab-deploy [action]
  204.  
  205. Deploy and configure virtual Red Hat Openstack Director lab - Version $VERSION
  206.  
  207. ACTIONS
  208. ========
  209.    libvirt-deploy         Configure hypervisor and define VMs/Virtual networks
  210.    idm-deploy             Deploy Red Hat IDM (IPA) as container on the hypervisor.
  211.    undercloud-install     Prepare the undercloud base system for deployment
  212.    overcloud-register     Upload overcloud images to glance and register overcloud nodes to Ironic.
  213.    howto                  Display a quick howto
  214. "
  215. }
  216.  
  217. function howto()
  218. {
  219.   >&2 echo "
  220.  ----- How to use osp-lab-deploy -----
  221.  
  222. You are using osp-lab-deploy version $VERSION
  223.  
  224. Synopsis
  225. ========
  226.    The program deploys a virtual enviroment ready to use for playing with Red Hat Director.
  227.    Virtual enviroment is based on KVM/Libvirt - By default, 10 VMs will be defined + 1 Provisioning Network.
  228.    * 1 Undercloud VM
  229.    * 3 Controllers VMs
  230.    * 2 Compute VMs
  231.    * 3 Ceph VMs
  232.    * 1 Custom node (Networker profile by default)
  233.  
  234.    Please NOTE that the script will only deploy the undercloud, other VMs are blank, ready to be deployed by Red Hat Director.
  235.    You can customise the number of VMs of their configuration by editing the script and setting the appropriate options.
  236.  
  237.    Optionally you can setup a IDM container if you want to deploy OSP with TLS everywhere.
  238.  
  239. Automation
  240. ==========
  241.    If you want to automate the whole process please use smack-my-node-up.sh
  242.    See https://gitlab.cee.redhat.com/gcharot/osp-enablement-tools/blob/master/deployment-tools/smack-my-node-up.sh
  243.  
  244. Pre-requisites
  245. ==============
  246.  
  247.    - A baremetal hypervisor with a pre-installed RHEL system, a minimum of 64GB RAM is strongly adviced.
  248.    - Please set the CPU and Memory value for each VM flavor by editing the required variables at the begining of the script.
  249.    - Adjust the number of VMs you would like to define.
  250.    - Likewise set the RHEL and OSP version you would like to use. Default is RHEL 7 and OSP10.
  251.  
  252.  
  253. Deploying the environment
  254. =========================
  255.  
  256.    Deployment is acheived in four steps :
  257.  
  258.    1) Hypervisor configuration and VM's definition
  259.      - Run \"osp-lab-deploy.sh libvirt-deploy\" as root on the hypervisor
  260.      - REBOOT your hypervisor
  261.  
  262.    1b) If you want to deploy IDM (DEPLOY_IDM=yes) then
  263.      - Run \"osp-lab-deploy.sh idm-deploy\" as root on the hypervisor
  264.  
  265.    2) Undercloud preparation
  266.      - SSH into the undercloud node as root \"ssh root@undercloud\"
  267.      - Run \"sh /tmp/osp-lab-deploy.sh undercloud-install\"
  268.      - REBOOT the undercloud VM
  269.  
  270.    3) Undercloud installation
  271.      - Once rebooted ssh back to the undercloud VM as stack user  \"ssh stackl@undercloud\"
  272.      - Check the ~/undercloud.conf file, modify it if needed.
  273.      - Install the undercloud as stack user \"openstack undercloud install\"
  274.  
  275.    4) Configure and register nodes
  276.      - Run \"sh /tmp/osp-lab-deploy.sh overcloud-register\" as stack user.
  277.      - Check everything is fine.
  278.  
  279.    You're all set ! Happy hacking !!!
  280.  
  281.    Please send feedback and bugs to gcharot@redhat.com
  282.  
  283.    --- The Field PM Team ---
  284. "
  285.  
  286. }
  287.  
  288.  
  289. #
  290. #  Setup rhos-release
  291. #
  292.  
  293. function setup_rhos_release()
  294. {
  295.  
  296.   echoinfo "Installing rhos-release..."
  297.  
  298.   if (rpm -q rhos-release);
  299.     then
  300.     echoinfo "rhos-release already installed, skipping !"
  301.     echoinfo "Removing current configured repositories"
  302.     yum clean all
  303.     rhos-release -x
  304.   else
  305.     rpm -ivh http://rhos-release.virt.bos.redhat.com/repos/rhos-release/rhos-release-latest.noarch.rpm || { echoerr "Unable to install rhos-realease"; return 1; }
  306.   fi
  307.  
  308.  
  309.   # If we are on the hypervisor then install the latest puddles
  310.   # TODO: Do this for RHN...
  311.   if !(grep hypervisor /proc/cpuinfo &> /dev/null);
  312.     then
  313.     echoinfo "Hypervisor detected, installing latest puddle release..."
  314.     rhos-release latest-released || { echoerr "Unable to configure rhos-realease to latest-released"; return 1; }
  315.     return 0
  316.   fi
  317.  
  318.   echoinfo "Configuring rhos-release to OSP $RHOS_VERSION..."
  319.   rhos-release ${RHOS_VERSION}-cdn -p passed_phase2 || { echoerr "Unable to configure rhos-realease to ${RHOS_VERSION}-cdn"; return 1; }
  320.  
  321.   # Set sub mechanism free OSP major version
  322.   OSP_VERSION=$RHOS_VERSION
  323.  
  324. }
  325.  
  326.  
  327. #
  328. #  Setup RHN
  329. #
  330.  
  331. function setup_rhn()
  332. {
  333.  
  334.   if [ -z $RHN_PASSWD ]; then
  335.     echo -n "No RHN Password submitted please enter your RHN password for account $RHN_USERNAME: "
  336.     read -s RHN_PASSWD
  337.     echo
  338.   fi
  339.  
  340.   echoinfo "Registering to RHN..."
  341.   subscription-manager register --username=$RHN_USERNAME --password=$RHN_PASSWD || { echoerr "Unable to register"; return 1; }
  342.  
  343.   echoinfo "Looking for Employee SKU POOL ID..."
  344.   RHN_POOLID=$(subscription-manager list --available --matches="Employee SKU" --pool-only | head -n1)
  345.  
  346.   if [ -z $RHN_POOLID ];
  347.     then
  348.     echoerr "Unable to find Employee SKU POOL ID"
  349.     return 1
  350.   else
  351.     echoinfo "Found POOL ID $RHN_POOLID"
  352.   fi
  353.  
  354.   echoinfo "Attaching pool $RHN_POOLID..."
  355.   subscription-manager attach --pool=$RHN_POOLID || { echoerr "Unable to attach Employee SKU POOL ID"; return 1; }
  356.  
  357.   echoinfo "Configuring repositories..."
  358.   subscription-manager repos --disable=* &>/dev/null
  359.   subscription-manager repos --enable=rhel-${RHEL_MAJ_VERSION}-server-rpms --enable=rhel-${RHEL_MAJ_VERSION}-server-extras-rpms \
  360. --enable=rhel-${RHEL_MAJ_VERSION}-server-rh-common-rpms --enable=rhel-ha-for-rhel-${RHEL_MAJ_VERSION}-server-rpms \
  361. --enable=rhel-${RHEL_MAJ_VERSION}-server-openstack-${OSP_MAJ_VERSION}-rpms || { echoerr "Unable to enable required repositories"; return 1; }
  362.  
  363.   # Set sub mechanism free OSP major version
  364.   OSP_VERSION=$OSP_MAJ_VERSION
  365.  
  366. }
  367.  
  368. #
  369. #  Install required packages
  370. #
  371.  
  372. function install_packages()
  373. {
  374.   local pkg_list=$1
  375.  
  376.   echoinfo "---===== Configuring repositories =====---"
  377.  
  378.   if [ "$SUB_TYPE" = "rhos-release" ];
  379.     then
  380.     setup_rhos_release || exit_on_err
  381.   elif [ "$SUB_TYPE" = "rhn" ];
  382.     then
  383.     setup_rhn || exit_on_err
  384.   else
  385.     echoerr "Incorrect registration option specified : $SUB_TYPE - Correct values are rhos-release or rhn"
  386.     return 1
  387.   fi
  388.  
  389. # Check Ironic driver
  390.   if [ "$IRONIC_DRIVER" = "vbmc" ];
  391.     then
  392.     echoinfo "Virtual BMC Ironic driver selected"
  393.   elif [ "$IRONIC_DRIVER" = "ssh" ];
  394.     then
  395.     echoinfo "Pxe SSH Ironic driver selected"
  396.   else
  397.     echoerr "Incorrect Ironic Driver selected : $IRONIC_DRIVER ! Accepted values are ssh or vbmc"
  398.     return 1
  399.   fi
  400.  
  401.  
  402.   echoinfo "---===== Installing Packages =====---"
  403.  
  404.   echoinfo "Updating system..."
  405.   yum update -y || { echoerr "Unable to update system"; return 1; }
  406.  
  407.   echoinfo "Installing required packages..."
  408.   yum install $pkg_list -y || { echoerr "Unable to install required packages"; return 1; }
  409.  
  410. }
  411.  
  412.  
  413.  
  414. ##########################################################################
  415. #                                                                        #
  416. #                     Hypervisor & Libvirt functions                     #
  417. #                                                                        #
  418. ##########################################################################
  419.  
  420.  
  421. #
  422. #  Check dependencies + some sanity checks
  423. #
  424.  
  425. function check_requirements()
  426. {
  427.  
  428.   # List of command dependencies
  429.   local bin_dep="virsh virt-install qemu-img virt-resize virt-filesystems virt-customize"
  430.  
  431.   if [ "$IRONIC_DRIVER" = "vbmc" ];
  432.     then
  433.     bin_dep="$bin_dep vbmc"
  434.   fi
  435.  
  436.   echoinfo "---===== Checking dependencies =====---"
  437.  
  438.   for cmd in $bin_dep; do
  439.     echoinfo "Checking for $cmd..."
  440.     $cmd --version  >/dev/null 2>&1 || { echoerr "$cmd cannot be found... Aborting"; return 1; }
  441.   done
  442.  
  443.    echoinfo "---===== Performing sanity checks =====---"
  444.  
  445.   if [ "$CEPH_OSD_DISK" -lt 1 ];
  446.     then
  447.     echoerr "You need to have at least one additional disk (OSD) attached to your Ceph nodes - Please configure the CEPH_OSD_DISK variable accordingly"
  448.     return 1
  449.   fi
  450.  
  451. }
  452.  
  453.  
  454. #
  455. #  Miscellaneous system config
  456. #
  457.  
  458. function libv_misc_sys_config()
  459. {
  460.  
  461.   echoinfo "---===== Misc System Config =====---"
  462.  
  463.  
  464.   echoinfo "Creating system user stack..."
  465.   useradd stack
  466.  
  467.   echoinfo "Setting stack user password to redhat"
  468.   echo "redhat" | passwd stack --stdin
  469.  
  470.   echoinfo "Configuring /etc/modprobe.d/kvm_intel.conf"
  471.   cat << EOF > /etc/modprobe.d/kvm_intel.conf
  472. options kvm-intel nested=1
  473. options kvm-intel enable_shadow_vmcs=1
  474. options kvm-intel enable_apicv=1
  475. options kvm-intel ept=1
  476. EOF
  477.  
  478.  
  479.   echoinfo "Configuring /etc/sysctl.d/98-rp-filter.conf"
  480.   cat << EOF > /etc/sysctl.d/98-rp-filter.conf
  481. net.ipv4.conf.default.rp_filter = 0
  482. net.ipv4.conf.all.rp_filter = 0
  483. EOF
  484.  
  485.   echoinfo "Applying RP filter on running interfaces"
  486.   for i in $(sysctl -A | grep "\.rp_filter"  | cut -d" " -f1); do
  487.    sysctl $i=0
  488.   done
  489.  
  490.   echoinfo "Configuring  /etc/polkit-1/localauthority/50-local.d/50-libvirt-user-stack.pkla"
  491.   cat << EOF > /etc/polkit-1/localauthority/50-local.d/50-libvirt-user-stack.pkla
  492. [libvirt Management Access]
  493. Identity=unix-user:stack
  494. Action=org.libvirt.unix.manage
  495. ResultAny=yes
  496. ResultInactive=yes
  497. ResultActive=yes
  498. EOF
  499.  
  500.   echoinfo "Creating SSH keypair"
  501.   if [ -e ~/.ssh/id_rsa ]; then
  502.     echoinfo "SSH keypair already exists, skipping..."
  503.   else
  504.     ssh-keygen -b 2048 -t rsa -f ~/.ssh/id_rsa -q -N ""
  505.   fi
  506.  
  507.   echoinfo "Starting Libvirtd"
  508.   systemctl start libvirtd || { echoerr "Unable to start libvirtd"; return 1; }
  509.  
  510.   echoinfo "Ensuring IPTables service is disabled"
  511.   systemctl disable --now iptables.service
  512.  
  513.   echoinfo "Ensuring firewalld is enabled and running"
  514.   systemctl enable --now firewalld || { echoerr "Unable to start firewalld"; return 1; }
  515.  
  516.  
  517.   echoinfo "Configuring Squid"
  518.   # Allow squid client to connect to https servers other than 443
  519.   sed -i 's/\(http_access deny !Safe_ports\)/#\1/; s/\(http_access deny CONNECT !SSL_ports\)/#\1/' /etc/squid/squid.conf
  520.   systemctl enable squid || { echoerr "Unable to enable Squid"; return 1; }
  521.   systemctl start  squid || { echoerr "Unable to start Squid"; return 1; }
  522.   firewall-cmd --permanent --add-service=squid
  523.   firewall-cmd --reload
  524.  
  525. }
  526.  
  527.  
  528. #
  529. #  Disable DHCP on default network + create provisioning network
  530. #
  531. function define_virt_net()
  532. {
  533.  
  534.   echoinfo "---===== Create virtual networks =====---"
  535.  
  536.  
  537.   cat > /tmp/provisioning.xml <<EOF
  538. <network>
  539.   <name>provisioning</name>
  540.   <ip address="172.16.0.254" netmask="255.255.255.0"/>
  541. </network>
  542. EOF
  543.  
  544.   echoinfo "Defining provisioning network..."
  545.   virsh net-define /tmp/provisioning.xml || { echoerr "Unable to define provisioning network"; return 1; }
  546.  
  547.   echoinfo "Setting net-autostart to provisioning network..."
  548.   virsh net-autostart provisioning || { echoerr "Unable to configure provisioning network"; return 1; }
  549.  
  550.   echoinfo "Starting provisioning network..."
  551.   virsh net-start provisioning || { echoerr "Unable to start provisioning network"; return 1; }
  552.  
  553.   echoinfo "Disabling DHCP on default network..."
  554.   if(virsh net-dumpxml default | grep dhcp &>/dev/null); then
  555.       virsh net-update default delete ip-dhcp-range "<range start='192.168.122.2' end='192.168.122.254'/>" --live --config || { echoerr "Unable to disable DHCP on default network"; return 1; }
  556.   else
  557.     echoinfo "DHCP already disabled, skipping"
  558.   fi
  559. }
  560.  
  561. #
  562. #  Create generic RHEL image disk
  563. #
  564. function define_basic_image()
  565. {
  566.  
  567.   echoinfo "---===== Create generic RHEL image =====---"
  568.  
  569.   pushd ${LIBVIRT_D}/images/
  570.   echoinfo "Downloading basic RHEL image from $RHEL_IMAGE_U..."
  571.   curl -o rhel7-guest-official.qcow2 $RHEL_IMAGE_U || { echoerr "Unable to download RHEL IMAGE"; return 1; }
  572.  
  573.   echoinfo "Cloning RHEL image to a 100G sparse image..."
  574.   qemu-img create -f qcow2 rhel7-guest.qcow2 100G || { echoerr "Unable to create sparse clone"; return 1; }
  575.  
  576.  
  577.   echoinfo "Checking image disk size..."
  578.   qemu-img info rhel7-guest.qcow2  | grep 100G  &>/dev/null || { echoerr "Incorrect image disk size"; return 1; }
  579.  
  580.   echoinfo "Extending file system..."
  581.   virt-resize --expand /dev/sda1 rhel7-guest-official.qcow2 rhel7-guest.qcow2 || { echoerr "Unable to extend file system"; return 1; }
  582.  
  583.   echoinfo "Checking image filesystem size..."
  584.   virt-filesystems --long -h  -a rhel7-guest.qcow2 | grep 100G &> /dev/null || { echoerr "Incorrect image filesystem size"; return 1; }
  585.  
  586.   echoinfo "Deleting old image..."
  587.   rm -f rhel7-guest-official.qcow2
  588.  
  589.   popd
  590. }
  591.  
  592.  
  593. #
  594. #  Define & setup undercloud VM
  595. #
  596. function define_undercloud_vm()
  597. {
  598.  
  599.   echoinfo "---===== Create Undercloud VM =====---"
  600.  
  601.   pushd ${LIBVIRT_D}/images/
  602.   echoinfo "Create disk from generic image..."
  603.  
  604.   qemu-img create -f qcow2 -b rhel7-guest.qcow2 undercloud.qcow2 || { echoerr "Unable to create undercloud disk image"; return 1; }
  605.  
  606.   echoinfo "Customizing VM..."
  607.   virt-customize -a undercloud.qcow2 --root-password password:redhat --ssh-inject "root:file:/root/.ssh/id_rsa.pub" --selinux-relabel --run-command 'yum remove cloud-init* -y && cp /etc/sysconfig/network-scripts/ifcfg-eth{0,1} && sed -i s/ONBOOT=.*/ONBOOT=no/g /etc/sysconfig/network-scripts/ifcfg-eth0 && cat << EOF > /etc/sysconfig/network-scripts/ifcfg-eth1
  608. DEVICE=eth1
  609. ONBOOT=yes
  610. IPADDR=192.168.122.253
  611. NETMASK=255.255.255.0
  612. GATEWAY=192.168.122.1
  613. NM_CONTROLLED=no
  614. DNS1=192.168.122.1
  615. DOMAIN=redhat.local
  616. EOF' || { echoerr "Unable to customise undercloud VM"; return 1; }
  617.  
  618.  
  619.   echoinfo "Creating undercloud VM: ${UNDERC_VCPU}vCPUs / ${UNDERC_MEM}MB RAM..."
  620.   virt-install --ram $UNDERC_MEM --vcpus $UNDERC_VCPU --os-variant rhel7 \
  621.     --disk path=${LIBVIRT_D}/images/undercloud.qcow2,device=disk,bus=virtio,format=qcow2 \
  622.     --import --noautoconsole --vnc --network network:provisioning \
  623.     --network network:default --name undercloud || { echoerr "Unable to create undercloud VM"; return 1; }
  624.  
  625.   popd
  626.  
  627.   echoinfo "Enable undercloud VM at hypervisor boot"
  628.   virsh autostart undercloud || { echoerr "Unable to set autostart on undercloud VM"; return 1; }
  629.  
  630.   echoinfo "Configuring /etc/hosts..."
  631.   echo -e "192.168.122.253\t\tundercloud.redhat.local\tundercloud" >> /etc/hosts
  632.  
  633. # Remove entry from known_host just in case
  634.   sed -ie '/undercloud/d' ~/.ssh/known_hosts &> /dev/null
  635.  
  636.  
  637.   echoinfo "Waiting for undercloud to come up"
  638.  
  639.  
  640.   sleep 10
  641.  
  642.   local nb_tries=0       # Number of SSH connections to try
  643.   local success=0        # Set to 1 if connection worked
  644.  
  645.   until [ $nb_tries -ge 5 ]
  646.    do
  647.  
  648.     ssh -o ConnectTimeout=3 -o StrictHostKeyChecking=no root@undercloud "uptime" &> /dev/null
  649.  
  650.     if [ $? -eq 0 ]; then
  651.       echoinfo "Successfully connected to the undercloud"
  652.       success=1
  653.       break
  654.     fi
  655.  
  656.     nb_tries=$[$nb_tries+1]
  657.     sleep 10
  658.  
  659.    done
  660.  
  661.   if [ $success -eq 0 ]; then
  662.     echoerr "Unable to SSH to the undercloud - Has it rebooted properly ?"
  663.     return 1
  664.   fi
  665.  
  666.   echoinfo "SCP script to undercloud..."
  667.   scp -o StrictHostKeyChecking=no $WHO_I_AM root@undercloud:/tmp || { echoerr "Unable to copy $WHO_I_AM to undercloud"; return 1; }
  668.   echo
  669. }
  670.  
  671.  
  672. #
  673. #  Define overcloud VMs
  674. #
  675. function define_overcloud_vms()
  676. {
  677.  
  678.   echoinfo "---===== Create overcloud VMs =====---"
  679.  
  680.   cd ${LIBVIRT_D}/images/
  681.  
  682.   for i in $ALL_N;
  683.     do
  684.       echoinfo "Creating disk image for node $i..."
  685.       qemu-img create -f qcow2 -o preallocation=metadata overcloud-$i.qcow2 100G || { echoerr "Unable to define disk overcloud-$i.qcow2"; return 1; }
  686.   done
  687.  
  688.   for i in $CEPH_N;
  689.     do
  690.         echoinfo "Creating additional disk's image(s) for node $i..."
  691.         for((n=1;n<=$CEPH_OSD_DISK;n+=1)); do
  692.           echoinfo "Creating additional disk $n - ${LIBVIRT_D}/images/overcloud-${i}-storage-${n}.qcow2"
  693.           qemu-img create -f qcow2 -o preallocation=metadata overcloud-${i}-storage-${n}.qcow2 100G || { echoerr "Unable to define disk overcloud-$i-storage-${n}.qcow2"; return 1; }
  694.         done
  695.         echo
  696.   done
  697.  
  698.  
  699.  
  700.   echoinfo "Defining controller nodes..."
  701.   echo
  702.  
  703.   for i in $CTRL_N;
  704.   do
  705.       echoinfo "Defining node overcloud-$i..."
  706.       virt-install --ram $CTRL_MEM --vcpus $CTRL_VCPU --os-variant rhel7 \
  707.       --disk path=${LIBVIRT_D}/images/overcloud-$i.qcow2,device=disk,bus=virtio,format=qcow2 \
  708.       --noautoconsole --vnc --network network:provisioning \
  709.       --network network:default --network network:default \
  710.       --name overcloud-$i \
  711.       --cpu SandyBridge,+vmx \
  712.       --dry-run --print-xml > /tmp/overcloud-$i.xml;
  713.  
  714.       # Fix for OSP10 + vBMC
  715.       sed -i "/<os>/a\    <bios rebootTimeout='0'\/>" /tmp/overcloud-$i.xml
  716.  
  717.       virsh define --file /tmp/overcloud-$i.xml || { echoerr "Unable to define overcloud-$i"; return 1; }
  718.   done
  719.  
  720.   echoinfo "Defining compute nodes..."
  721.   echo
  722.  
  723.   for i in $COMPT_N;
  724.   do
  725.       echoinfo "Defining node overcloud-$i..."
  726.       virt-install --ram $COMPT_MEM --vcpus $COMPT_VCPU --os-variant rhel7 \
  727.       --disk path=${LIBVIRT_D}/images/overcloud-$i.qcow2,device=disk,bus=virtio,format=qcow2 \
  728.       --noautoconsole --vnc --network network:provisioning \
  729.       --network network:default --network network:default \
  730.       --name overcloud-$i \
  731.       --cpu SandyBridge,+vmx \
  732.       --dry-run --print-xml > /tmp/overcloud-$i.xml
  733.  
  734.       # Fix for OSP10 + vBMC
  735.       sed -i "/<os>/a\    <bios rebootTimeout='0'\/>" /tmp/overcloud-$i.xml
  736.  
  737.       virsh define --file /tmp/overcloud-$i.xml || { echoerr "Unable to define overcloud-$i"; return 1; }
  738.   done
  739.  
  740.  
  741.   echoinfo "Defining ceph nodes..."
  742.   echo
  743.  
  744.   for i in $CEPH_N;
  745.   do
  746.       echoinfo "Defining node overcloud-$i..."
  747.       virt-install --ram $CEPH_MEM --vcpus $CEPH_VCPU --os-variant rhel7 \
  748.       --disk path=${LIBVIRT_D}/images/overcloud-$i.qcow2,device=disk,bus=virtio,format=qcow2 \
  749.       $(for((n=1;n<=$CEPH_OSD_DISK;n+=1)); do echo -n "--disk path=${LIBVIRT_D}/images/overcloud-$i-storage-${n}.qcow2,device=disk,bus=virtio,format=qcow2 "; done) \
  750.       --noautoconsole --vnc --network network:provisioning \
  751.       --network network:default --network network:default \
  752.       --name overcloud-$i \
  753.       --cpu SandyBridge,+vmx \
  754.       --dry-run --print-xml > /tmp/overcloud-$i.xml
  755.  
  756.       # Fix for OSP10 + vBMC
  757.       sed -i "/<os>/a\    <bios rebootTimeout='0'\/>" /tmp/overcloud-$i.xml
  758.  
  759.       virsh define --file /tmp/overcloud-$i.xml || { echoerr "Unable to define overcloud-$i"; return 1; }
  760.   done
  761.  
  762.  
  763.   echoinfo "Defining custom nodes..."
  764.   echo
  765.  
  766.   for i in $CUST_N;
  767.   do
  768.       echoinfo "Defining custom node overcloud-$i..."
  769.  
  770.       virt-install --ram $CUST_MEM --vcpus $CUST_VCPU --os-variant rhel7 \
  771.         --disk path=${LIBVIRT_D}/images/overcloud-$i.qcow2,device=disk,bus=virtio,format=qcow2 \
  772.         --noautoconsole --vnc --network network:provisioning \
  773.         --network network:default --network network:default \
  774.         --name overcloud-$i \
  775.         --cpu SandyBridge,+vmx \
  776.         --dry-run --print-xml > /tmp/overcloud-$i.xml
  777.  
  778.         # Fix for OSP10 + vBMC
  779.         sed -i "/<os>/a\    <bios rebootTimeout='0'\/>" /tmp/overcloud-$i.xml
  780.  
  781.       virsh define --file /tmp/overcloud-$i.xml || { echoerr "Unable to define overcloud-$i..."; return 1; }
  782.   done
  783.  
  784.   rm -f /tmp/overcloud-*
  785.  
  786.  
  787. }
  788.  
  789. function configure_vbmc()
  790. {
  791.  
  792.   echoinfo "---===== Configuring Virtual BMC =====---"
  793.  
  794.  
  795.   echoinfo "Setting up dummy IPs..."
  796.   echoinfo "Adding dummy kernel module at system boot"
  797.   echo dummy > /etc/modules-load.d/dummy.conf
  798.   echoinfo "Generating config file /etc/sysconfig/network-scripts/ifcfg-dummy0"
  799.  
  800.   cat << EOF > /etc/sysconfig/network-scripts/ifcfg-dummy0
  801. DEVICE=dummy0
  802. ONBOOT=yes
  803. NM_CONTROLLED="no"
  804. IPADDR=192.168.1.1
  805. PREFIX=24
  806. $(for ((i=2;i<=20;i++)); do
  807. echo IPADDR${i}=192.168.1.${i}
  808. echo PREFIX${i}=24
  809. done)
  810. EOF
  811.  
  812.   echoinfo "Loading dummy kernel module"
  813.   modprobe dummy || { echoerr "Unable to load dummy kernel module"; return 1; }
  814.  
  815.   echoinfo "Bringing up dummy0 interface"
  816.   ifup dummy0 || { echoerr "Unable to bring up dummy0 interface"; return 1; }
  817.  
  818.   echoinfo "Creating VirtualBMC systemd unit file"
  819.   cat << EOF > /usr/lib/systemd/system/virtualbmc@.service
  820. [Unit]
  821. Description=VirtualBMC %i service
  822. After=network.target libvirtd.services
  823.  
  824. [Service]
  825. Type=forking
  826. PIDFile=/root/.vbmc/%i/pid
  827. ExecStart=/bin/vbmc start %i
  828. ExecStop=/bin/vbmc stop %i
  829. Restart=always
  830.  
  831. [Install]
  832. WantedBy=multi-user.target
  833. EOF
  834.  
  835.   echoinfo "Configure Firewall for vBMC..."
  836.   echoinfo "Opening port 623/udp"
  837.   sudo firewall-cmd --zone=public --add-port=623/udp --permanent || { echoerr "Unable to open port 623/udp..."; return 1; }
  838.  
  839.   echoinfo "Restarting firewall"
  840.   firewall-cmd --reload || { echoerr "Unable to restart firewalld..."; return 1; }
  841.  
  842.   echoinfo "Adding nodes to Virtual BMC..."
  843.  
  844.   count=1
  845.   for i in $(virsh list --all | awk ' /overcloud/ {print $2}'); do
  846.     echoinfo "Adding node $i to Virtual BMC"
  847.     vbmc add $i --address 192.168.1.${count} --username admin --password redhat || { echoerr "Unable to add $i to Virtual BMC..."; return 1; }
  848.  
  849.     echoinfo "Starting Virtual BMC service for node $i"
  850.     systemctl enable --now virtualbmc@${i} || { echoerr "Unable to start Virtual BMC service for $i..."; return 1; }
  851.  
  852.     echoinfo "Testing IPMI connection on node $i"
  853.     ipmitool -I lanplus -U admin -P redhat  -H 192.168.1.${count}  power status || { echoerr "IPMI test on node $i failed..."; return 1; }
  854.  
  855.     count=$((count+1))
  856.   done
  857.  
  858.  
  859.   echoinfo "Setting VirtualBMC sudo permissions for stack users"
  860.   echo -e "stack\tALL=(root)\tNOPASSWD:/usr/bin/vbmc" > /etc/sudoers.d/vbmc
  861.  
  862. }
  863.  
  864.  
  865.  
  866. #
  867. #  Summary output
  868. #
  869. function libv_post_install_output()
  870. {
  871.  
  872.   echo
  873.   echoinfo "---===== SUMMARY =====---"
  874.   echo
  875.  
  876.   echo "You can connect to the undercloud VM with ssh root@undercloud / p: redhat / IP : 192.168.122.253"
  877.   echo
  878.   echo "Two virtual networks have been set"
  879.   echo "- Default : 192.168.122.0/24 / GW : 192.168.122.1"
  880.   echo "- Provisioning : 172.16.0.0/24 / GW : 172.16.0.254"
  881.   echo
  882.   echo "List your VMs with virsh list --all"
  883.  
  884.   echo
  885.   echo "Use default network for overcloud traffic - Use eth1 & eth2 for bonding"
  886.   echo
  887.   echoinfo "Next steps :"
  888.   echo "---- ${RED} !!! PLEASE REBOOT YOUR SYSTEM !!! ${NORMAL}----"
  889.   echo "- Optional Run \"osp-lab-deploy.sh idm-deploy\" as root on the hypervisor if you've set DEPLOY_IDM=yes"
  890.   echo "- ssh root@undercloud"
  891.   echo "- run sh /tmp/osp-lab-deploy.sh undercloud-install as root"
  892.   echo
  893.   echo "Happy hacking !!! - The field PM Team"
  894.  
  895. }
  896.  
  897. function libvirt_deploy()
  898. {
  899.  
  900.   echoinfo "Checking UID..."
  901.   if [ $UID -ne 0 ]; then
  902.     echoerr "Please run this script as root"
  903.     exit_on_err
  904.   fi
  905.  
  906.   install_packages "$PKG_HYPERVISOR" || exit_on_err
  907.   check_requirements || exit_on_err
  908.   libv_misc_sys_config || exit_on_err
  909.   define_virt_net || exit_on_err
  910.   define_basic_image || exit_on_err
  911.   define_undercloud_vm || exit_on_err
  912.   define_overcloud_vms || exit_on_err
  913.   if [ "$IRONIC_DRIVER" = "vbmc" ];
  914.     then
  915.     configure_vbmc || exit_on_err
  916.   fi
  917.   libv_post_install_output
  918.  
  919. }
  920.  
  921.  
  922. ##########################################################################
  923. #                                                                        #
  924. #                      Undercloud install functions                      #
  925. #                                                                        #
  926. ##########################################################################
  927.  
  928.  
  929. #
  930. #  Miscellaneous system config
  931. #
  932. function undercloud_misc_sys_config()
  933. {
  934.  
  935.   echoinfo "---===== Misc System Config =====---"
  936.  
  937.   echoinfo "Setting Hostname to undercloud.redhat.local"
  938.   hostnamectl set-hostname undercloud.redhat.local || { echoerr "Unable to set hostname undercloud.redhat.local"; return 1; }
  939.  
  940. # Set undercloud DNS to IPA IP if DEPLOY_IDM="yes"
  941.   if [ $DEPLOY_IDM = "yes" ]; then
  942.   sed -i "/DNS1=/c\DNS1=$IDM_BIND_IP" /etc/sysconfig/network-scripts/ifcfg-eth1 || { echoerr "Unable to set DNS to $IDM_BIND_IP"; return 1; }
  943.   fi
  944.  
  945.   echoinfo "Restarting network service"
  946.   systemctl  restart network || { echoerr "Unable to restart network service"; return 1; }
  947.  
  948.   echoinfo "Populating Hosts file"
  949.   ipaddr=$(facter ipaddress_eth1)
  950.   echo -e "$ipaddr\t\tundercloud.redhat.local\tundercloud" >> /etc/hosts
  951.  
  952.   echoinfo "Creating system user stack..."
  953.   useradd stack
  954.  
  955.   echoinfo "Setting stack user password to redhat"
  956.   echo "redhat" | passwd stack --stdin
  957.  
  958.   echoinfo "Creating SSH keypair"
  959.   if [ -e /home/stack/.ssh/id_rsa ]; then
  960.     echoinfo "SSH keypair already exists, skipping..."
  961.   else
  962.     sudo -u stack ssh-keygen -b 2048 -t rsa -f /home/stack/.ssh/id_rsa -q -N ""
  963.   fi
  964.  
  965.   echoinfo "Adding hypervisor's SSH key to stack user authorized_keys"
  966.   cp /root/.ssh/authorized_keys /home/stack/.ssh/authorized_keys
  967.   chown stack:stack /home/stack/.ssh/authorized_keys
  968.  
  969.   echoinfo "Adding stack user to sudoers"
  970.   echo "stack ALL=(root) NOPASSWD:ALL" | tee -a /etc/sudoers.d/stack
  971.   chmod 0440 /etc/sudoers.d/stack
  972.  
  973.   echoinfo "Copying stack user SSH key to hypervisor..."
  974.   sudo -u stack sshpass -p 'redhat' ssh-copy-id -o StrictHostKeyChecking=no stack@192.168.122.1 || { echoerr "Unable to copy SSH key to hypervisor - Check password authentication is enabled"; return 1; }
  975.  
  976.   echoinfo "Testing virsh connection to hypervisor"
  977.   sudo -u stack virsh -c qemu+ssh://stack@192.168.122.1/system list || { echoerr "Unable to connect to the hypervisor"; return 1; }
  978.  
  979.   echoinfo "Disabling Libvirtd on the undercloud"
  980.   systemctl disable libvirtd
  981.  
  982. }
  983.  
  984.  
  985.  
  986.  
  987. function configure_undercloud()
  988. {
  989.  
  990.   echoinfo "Configuring undercloud.conf"
  991.  
  992.   sudo -u stack cp /usr/share/instack-undercloud/undercloud.conf.sample /home/stack/undercloud.conf || { echoerr "Failed to copy sample undercloud file to /home/stack/"; return 1; }
  993.  
  994.   sudo -u stack crudini --set /home/stack/undercloud.conf DEFAULT local_ip 172.16.0.1/24
  995.   sudo -u stack crudini --set /home/stack/undercloud.conf DEFAULT local_interface eth0
  996.   sudo -u stack crudini --set /home/stack/undercloud.conf DEFAULT masquerade_network 172.16.0.0/24
  997.  
  998.   if [ $OSP_VERSION -le 13 ]; then
  999.     sudo -u stack crudini --set /home/stack/undercloud.conf DEFAULT undercloud_public_vip  172.16.0.10
  1000.     sudo -u stack crudini --set /home/stack/undercloud.conf DEFAULT undercloud_admin_vip 172.16.0.11
  1001.     sudo -u stack crudini --set /home/stack/undercloud.conf DEFAULT dhcp_start 172.16.0.20
  1002.     sudo -u stack crudini --set /home/stack/undercloud.conf DEFAULT dhcp_end 172.16.0.120
  1003.     sudo -u stack crudini --set /home/stack/undercloud.conf DEFAULT network_cidr 172.16.0.0/24
  1004.     sudo -u stack crudini --set /home/stack/undercloud.conf DEFAULT network_gateway 172.16.0.1
  1005.     sudo -u stack crudini --set /home/stack/undercloud.conf DEFAULT discovery_iprange 172.16.0.150,172.16.0.180
  1006.     sudo -u stack crudini --set /home/stack/undercloud.conf DEFAULT inspection_iprange 172.16.0.150,172.16.0.180
  1007.     sudo -u stack crudini --set /home/stack/undercloud.conf DEFAULT generate_service_certificate false
  1008.  
  1009. # OSP14+ some undercloud.conf parameters change and the undercloud is now containerised
  1010.   else
  1011.     sudo -u stack crudini --set /home/stack/undercloud.conf DEFAULT undercloud_public_host 172.16.0.10
  1012.     sudo -u stack crudini --set /home/stack/undercloud.conf DEFAULT undercloud_admin_host 172.16.0.11
  1013.     sudo -u stack crudini --set /home/stack/undercloud.conf DEFAULT clean_nodes true
  1014.     sudo -u stack crudini --set /home/stack/undercloud.conf DEFAULT container_images_file /home/stack/undercloud-templates/containers-prepare-parameter.yaml
  1015.     sudo -u stack crudini --set /home/stack/undercloud.conf DEFAULT custom_env_files /home/stack/undercloud-templates/ntp.yaml
  1016.     sudo -u stack crudini --set /home/stack/undercloud.conf DEFAULT docker_insecure_registries docker-registry.engineering.redhat.com
  1017.  
  1018.     sudo -u stack crudini --set /home/stack/undercloud.conf ctlplane-subnet local_subnet ctlplane-subnet
  1019.     sudo -u stack crudini --set /home/stack/undercloud.conf ctlplane-subnet masquerade true
  1020.     sudo -u stack crudini --set /home/stack/undercloud.conf ctlplane-subnet cidr 172.16.0.0/24
  1021.     sudo -u stack crudini --set /home/stack/undercloud.conf ctlplane-subnet gateway 172.16.0.1
  1022.     sudo -u stack crudini --set /home/stack/undercloud.conf ctlplane-subnet inspection_iprange 172.16.0.150,172.16.0.180
  1023.     sudo -u stack crudini --set /home/stack/undercloud.conf ctlplane-subnet dhcp_start 172.16.0.20
  1024.     sudo -u stack crudini --set /home/stack/undercloud.conf ctlplane-subnet dhcp_end 172.16.0.120
  1025.  
  1026.     sudo -u stack mkdir /home/stack/undercloud-templates || { echoerr "Failed to create /home/stack/undercloud-templates directory"; return 1; }
  1027.  
  1028.     echoinfo "Generating containers-prepare-parameter.yaml..."
  1029.     sudo -u stack openstack tripleo container image prepare default  --local-push-destination  --output-env-file /home/stack/undercloud-templates/containers-prepare-parameter.yaml || \
  1030.     { echoerr "Failed to generate /home/stack/undercloud-templates/containers-prepare-parameter.yaml "; return 1; }
  1031. # Set container registry to internal one if using rhos-release
  1032. #    if [ "$SUB_TYPE" = "rhos-release" ]; then
  1033. #      sudo -u stack sed -i "s?registry.access.redhat.com/rhosp14?docker-registry.engineering.redhat.com/rhosp${OSP_VERSION}?" /home/stack/undercloud-templates/containers-prepare-parameter.yaml
  1034. #    fi
  1035.  
  1036.     echoinfo "Generating ntp.yaml"
  1037.     sudo -u stack cat << EOF > /home/stack/undercloud-templates/ntp.yaml
  1038. parameter_defaults:
  1039.   NtpServer: '10.16.255.1'
  1040. EOF
  1041.   fi
  1042.  
  1043.   if [ $DEPLOY_IDM = "yes" ]; then
  1044.  
  1045.     echoinfo "Installing novajoin..."
  1046.     sudo yum install -y python-novajoin || { echoerr "Failed to install python-novajoin"; return 1; }
  1047.  
  1048.     echoinfo "Getting OTP from IDM..."
  1049.     otp=$(sudo /usr/libexec/novajoin-ipa-setup \
  1050.       --principal admin \
  1051.       --password redhat42 \
  1052.       --server ipa.redhat.local \
  1053.       --realm REDHAT.LOCAL \
  1054.       --domain redhat.local \
  1055.       --hostname undercloud.redhat.local \
  1056.       --precreate)
  1057.  
  1058.     if [ $? -eq 0 ]; then
  1059.       echoinfo "Successfully retrieved OTP from IDM: $OTP"
  1060.     else
  1061.       echoerr "Failed to retrieve OTP password from IDM!"
  1062.       return 1
  1063.     fi
  1064.  
  1065.     echoinfo "Configuring IDM parameters in undercloud.conf"
  1066.     sudo -u stack crudini --set /home/stack/undercloud.conf DEFAULT enable_novajoin true
  1067.     sudo -u stack crudini --set /home/stack/undercloud.conf DEFAULT ipa_otp $otp
  1068.     sudo -u stack crudini --set /home/stack/undercloud.conf DEFAULT undercloud_hostname undercloud.redhat.local
  1069.     sudo -u stack crudini --set /home/stack/undercloud.conf DEFAULT overcloud_domain_name redhat.local
  1070.     sudo -u stack crudini --set /home/stack/undercloud.conf DEFAULT undercloud_nameservers $IDM_BIND_IP
  1071.   fi
  1072.  
  1073. }
  1074.  
  1075.  
  1076.  
  1077. #
  1078. #  Summary output
  1079. #
  1080. function undercloud_post_install_output()
  1081. {
  1082.  
  1083.   echo
  1084.   echoinfo "---===== SUMMARY =====---"
  1085.   echo
  1086.  
  1087.   echo "Base system and undercloud configuration completed !"
  1088.   echoinfo "Next steps :"
  1089.   echo "- !!!! REBOOT the undercloud VM !!!!"
  1090.   echo "- Check ~stack/undercloud.conf file"
  1091.   echo "- Run openstack undercloud install as stack user"
  1092.   echo "- Check the undercloud install is successful"
  1093.   echo "- Run osp-lab-deploy.sh overcloud-register as stack user"
  1094.  
  1095. }
  1096.  
  1097.  
  1098. function undercloud_install()
  1099. {
  1100.  
  1101.   echoinfo "Checking UID..."
  1102.   if [ $UID -ne 0 ]; then
  1103.     echoerr "Please run this script as root"
  1104.     exit_on_err
  1105.   fi
  1106.  
  1107.  
  1108.   install_packages "$PKG_UNDERCLOUD" || exit_on_err
  1109.   undercloud_misc_sys_config || exit_on_err
  1110.   configure_undercloud || exit_on_err
  1111.   undercloud_post_install_output
  1112.  
  1113. }
  1114.  
  1115.  
  1116. ##########################################################################
  1117. #                                                                        #
  1118. #                Undercloud node registration functions                  #
  1119. #                                                                        #
  1120. ##########################################################################
  1121.  
  1122.  
  1123.  
  1124. function upload_overcloud_image()
  1125. {
  1126.  
  1127.   echoinfo "---===== Upload Overcloud images =====---"
  1128.  
  1129.   echoinfo "Installing package rhosp-director-images..."
  1130.   sudo yum install rhosp-director-images -y || { echoerr "Unable to install package rhosp-director-images"; return 1; }
  1131.  
  1132.   echoinfo "Create /home/stack/images directory"
  1133.   mkdir -p ~/images/
  1134.   cd  ~/images/
  1135.  
  1136.   echoinfo "Extracting IPA image to ~/images..."
  1137.   tar xvf /usr/share/rhosp-director-images/ironic-python-agent.tar -C . || { echoerr "Unable to extract IPA image"; return 1; }
  1138.  
  1139.   echoinfo "Extracting overcloud image to ~/images..."
  1140.   tar xvf /usr/share/rhosp-director-images/overcloud-full.tar -C . || { echoerr "Unable to extract overcloud images"; return 1; }
  1141.  
  1142.   echoinfo "Customising overcloud image..."
  1143.   virt-customize -a ~/images/overcloud-full.qcow2 --root-password password:redhat --run-command "rpm -ivh http://rhos-release.virt.bos.redhat.com/repos/rhos-release/rhos-release-latest.noarch.rpm && rhos-release ${RHOS_VERSION}-cdn" || { echoerr "Unable to customise overcloud image"; return 1; }
  1144.  
  1145.   echoinfo "Uploading images to glance"
  1146.   openstack overcloud image upload || { echoerr "Failed to upload images to glance"; return 1; }
  1147. }
  1148.  
  1149. #
  1150. #  Dynamic instackenv generation for VirtualBMC (nasty bash)
  1151. #
  1152.  
  1153. function generate_instackenv_vbmc()
  1154. {
  1155.   echoinfo "Generating ~/instackenv.json file with VirtualBMC (pxe_ipmitool) driver..."
  1156.  
  1157.   echoinfo "Retrieving VirtualBMC assignments"
  1158.   ssh stack@192.168.122.1 sudo vbmc list | awk ' /overcloud/ {print $2" "$6}' > /tmp/vbmc_assign
  1159.  
  1160.   (
  1161.     count=1
  1162.  
  1163.     cat << EOF
  1164. {
  1165.   "nodes": [
  1166. EOF
  1167.  
  1168. for node in $ALL_N; do
  1169.  
  1170.     cat << EOF
  1171.     {
  1172.       "name": "overcloud-$node",
  1173.       "pm_addr": "$(grep overcloud-$node /tmp/vbmc_assign  | cut -d' ' -f2)",
  1174.       "pm_password": "redhat",
  1175.       "pm_type": "pxe_ipmitool",
  1176.       "mac": [
  1177.         "$(sed -n ${count}p /tmp/nodes.txt)"
  1178.       ],
  1179.       "pm_user": "admin"
  1180.     },
  1181. EOF
  1182.  
  1183.   (( count += 1 ))
  1184. done
  1185.  
  1186.     cat << EOF
  1187.   ]
  1188. }
  1189. EOF
  1190.   )>/tmp/instackenv.tmp
  1191.  
  1192. # Find the last '},' line so we can remove the ',' - yeah ugly hein :)
  1193. # TODO: Find something more elegant
  1194.   LINE=$(($(cat /tmp/instackenv.tmp | wc -l) - 2))
  1195.  
  1196. # Remove ',' from the last block
  1197.   sed -i -e "${LINE}s/,//g" /tmp/instackenv.tmp
  1198.  
  1199.   jq . /tmp/instackenv.tmp > ~/instackenv.json
  1200.  
  1201. }
  1202.  
  1203.  
  1204. #
  1205. #  Dynamic instackenv generation for PXE_SSH (nasty bash)
  1206. #
  1207.  
  1208. function generate_instackenv_ssh()
  1209. {
  1210.  
  1211.   echoinfo "Generating ~/instackenv.json file with pxe_ssh driver"
  1212.  
  1213.   (
  1214.     count=1
  1215.  
  1216.     cat << EOF
  1217. {
  1218.   "nodes": [
  1219. EOF
  1220.  
  1221. for node in $ALL_N; do
  1222.  
  1223.     cat << EOF
  1224.     {
  1225.       "pm_user": "stack",
  1226.       "mac": [
  1227.         "$(sed -n ${count}p /tmp/nodes.txt)"
  1228.       ],
  1229.       "pm_type": "pxe_ssh",
  1230.       "pm_password": "$(cat ~/.ssh/id_rsa)",
  1231.       "pm_addr": "192.168.122.1",
  1232.       "name": "overcloud-$node"
  1233.     },
  1234. EOF
  1235.  
  1236.   (( count += 1 ))
  1237. done
  1238.  
  1239.     cat << EOF
  1240.   ]
  1241. }
  1242. EOF
  1243.   )>/tmp/instackenv.tmp
  1244.  
  1245. # Find the last '},' line so we can remove the ',' - yeah ugly hein :)
  1246.   LINE=$(($(cat /tmp/instackenv.tmp | wc -l) - 2))
  1247.  
  1248. # Remove ',' from the last block
  1249.   sed -i -e "${LINE}s/,//g" /tmp/instackenv.tmp
  1250.  
  1251.   jq . /tmp/instackenv.tmp > ~/instackenv.json
  1252.  
  1253. }
  1254.  
  1255. #
  1256. #  Register overcloud nodes into undercloud's Ironic and introspect nodes
  1257. #
  1258.  
  1259. function register_overcloud_nodes()
  1260. {
  1261.   echoinfo "---===== Registering overcloud images =====---"
  1262.  
  1263.   cd ~
  1264.   echoinfo "Dumping overcloud's nodes provisioning MAC addresses to /tmp/nodes.txt"
  1265.   for i in $ALL_N; do
  1266.     echoinfo "Looking for node $i"
  1267.     virsh -c qemu+ssh://stack@192.168.122.1/system  domiflist overcloud-$i | awk '$3 == "provisioning" {print $5};' || { echoerr "Unable to get MAC address of node $i"; return 1; }
  1268.   done > /tmp/nodes.txt
  1269.  
  1270.  
  1271.   if [ "$IRONIC_DRIVER" = "vbmc" ];
  1272.     then
  1273.     generate_instackenv_vbmc
  1274.   elif [ "$IRONIC_DRIVER" = "ssh" ];
  1275.     then
  1276.     generate_instackenv_ssh
  1277.   else
  1278.     echoerr "Incorrect Ironic Driver selected : $IRONIC_DRIVER ! Accepted values are ssh or vbmc"
  1279.     return 1
  1280.   fi
  1281.  
  1282.  
  1283.   echoinfo "Importing overcloud nodes and introspecting nodes..."
  1284.   openstack overcloud node import --provide instackenv.json --introspect --provide --instance-boot-option local ||  { echoerr "Failed to import/instrospect nodes !"; return 1; }
  1285.  
  1286.   if [ $DEPLOY_IDM = "yes" ]; then
  1287.     local dns=$IDM_BIND_IP
  1288.   else
  1289.     local dns=192.168.122.1
  1290.   fi
  1291.  
  1292.   echoinfo "Setting DNS to $dns on Neutron provisioning network..."
  1293.   openstack subnet set --dns-nameserver $dns ctlplane-subnet
  1294.  
  1295.   echoinfo "Setting docker-registry.engineering.redhat.com to the list of insecure registries"
  1296.   sudo sed -i '/INSECURE_REGISTRY/c\INSECURE_REGISTRY="--insecure-registry 172.16.0.1:8787 --insecure-registry 172.16.0.11:8787 --insecure-registry docker-registry.engineering.redhat.com"' /etc/sysconfig/docker
  1297.   echoinfo "Restarting docker service"
  1298.   sudo systemctl restart docker
  1299.  
  1300. }
  1301.  
  1302.  
  1303. #
  1304. #  Tag overcloud nodes to their respective properties.
  1305. #
  1306.  
  1307. function tag_overcloud_nodes()
  1308. {
  1309.  
  1310.   local sched_incr=0
  1311.  
  1312.   echoinfo "---===== Tag overcloud images =====---"
  1313.  
  1314.   echoinfo "Tagging Controller nodes to $CTRL_FLAVOR profile and $CTRL_SCHED scheduler hint..."
  1315.   for i in $CTRL_N; do
  1316.     echoinfo "Setting up $i..."
  1317.     openstack baremetal node set overcloud-$i --property capabilities=profile:${CTRL_FLAVOR},node:${CTRL_SCHED}-${sched_incr},${CTRL_OTHER_PROP} || { echoerr "Setting Ironic properties on node $i failed !"; return 1; }
  1318.     ((sched_incr+=1))
  1319.   done
  1320.  
  1321.   echoinfo "Tagging Compute nodes to $COMPT_FLAVOR profile and $COMPT_SCHED scheduler hint..."
  1322.   sched_incr=0
  1323.   for i in $COMPT_N; do
  1324.     echoinfo "Setting up $i..."
  1325.     openstack baremetal node set overcloud-$i --property capabilities=profile:${COMPT_FLAVOR},node:${COMPT_SCHED}-${sched_incr},${COMPT_OTHER_PROP} || { echoerr "Setting Ironic properties on node $i failed !"; return 1; }
  1326.     ((sched_incr+=1))
  1327.   done
  1328.  
  1329.   echoinfo "Tagging Ceph nodes to $CEPH_FLAVOR profile and $CEPH_SCHED scheduler hint..."
  1330.   sched_incr=0
  1331.   for i in $CEPH_N; do
  1332.     echoinfo "Setting up $i..."
  1333.     openstack baremetal node set overcloud-$i --property capabilities=profile:${CEPH_FLAVOR},node:${CEPH_SCHED}-${sched_incr},${CEPH_OTHER_PROP} || { echoerr "Setting Ironic properties on node $i failed !"; return 1; }
  1334.     ((sched_incr+=1))
  1335.   done
  1336.  
  1337.   echoinfo "Tagging Custom nodes to $CUST_FLAVOR profile and $CUST_SCHED scheduler hint..."
  1338.   sched_incr=0
  1339.   for i in $CUST_N; do
  1340.     echoinfo "Setting up $i..."
  1341.     openstack baremetal node set overcloud-$i --property capabilities=profile:${CUST_FLAVOR},node:${CUST_SCHED}-${sched_incr},${CUST_OTHER_PROP} || { echoerr "Setting Ironic properties on node $i failed !"; return 1; }
  1342.     ((sched_incr+=1))
  1343.   done
  1344.  
  1345.  
  1346.   echoinfo "Creating $CUST_FLAVOR custom flavor..."
  1347.   openstack flavor create --id auto --ram 4096 --disk 40 --vcpus 1 $CUST_FLAVOR || { echoerr "Unable to create custom $CUST_FLAVOR flavor !"; return 1; }
  1348.   openstack flavor set  --property "capabilities:boot_option"="local" --property "capabilities:profile"=$CUST_FLAVOR $CUST_FLAVOR ||  { echoerr "Unable to configure networker flavor !"; return 1; }
  1349.  
  1350. }
  1351.  
  1352. # Configure IDM for overcloud LDAP authentication (service + tenant user). Non blocking function, script won't fail it something goes wrong.
  1353. function post_idm_config()
  1354. {
  1355.  
  1356.   echoinfo "---===== IDM post configuration  =====---"
  1357.  
  1358.   echoinfo "Authenticating to kerberos server as admin..."
  1359.   echo "redhat42" | kinit admin ||  { echoerr "Unable to login as admin!"; return 1; }
  1360.  
  1361.   echoinfo "Adding service user svc-ldap..."
  1362.   ipa user-add svc-ldap --first OpenStack --last RH
  1363.   echoinfo "Setting svc-ldap user password to \"redhat\""
  1364.   echo "redhat" | ipa passwd svc-ldap
  1365.  
  1366.   echoinfo "Adding group grp-openstack..."
  1367.   ipa group-add --desc="OpenStack Users" grp-openstack
  1368.   echoinfo "Adding svc-ldap to grp-openstack group..."
  1369.   ipa group-add-member --users=svc-ldap grp-openstack
  1370.  
  1371.   echoinfo "Adding OpenStack user test-user"
  1372.   ipa user-add test-user --first test --last user
  1373.   echoinfo "Setting test-user passwd to \"test\""
  1374.   echo "test" | ipa passwd test-user
  1375.   echoinfo "Adding test-user to grp-openstack group"
  1376.   ipa group-add-member --users=test-user grp-openstack
  1377.  
  1378. }
  1379.  
  1380. function overcloud_reg_post_install_output()
  1381. {
  1382.  
  1383.   echoinfo "Sucessfully uploaded overcloud image to glance"
  1384.   echoinfo "Sucessfully register overcloud nodes to ironic : $ALL_N"
  1385.   echoinfo "source ~/stackrc to start playing !!!"
  1386.   echo
  1387.   echo "Happy hacking !!! - The field PM Team"
  1388.  
  1389. }
  1390.  
  1391. function overcloud_register()
  1392. {
  1393.  
  1394.   echoinfo "Checking UID..."
  1395.   if [ $USER != "stack" ]; then
  1396.     echoerr "Please run this script as stack user"
  1397.     exit_on_err
  1398.   fi
  1399.  
  1400.   if [ -f ~/stackrc ]; then
  1401.     source ~/stackrc
  1402.   else
  1403.     echoerr "Unable to source ~/stackrc - Have you installed the undercloud ???"
  1404.     exit_on_err
  1405.   fi
  1406.  
  1407.  
  1408.   upload_overcloud_image || exit_on_err
  1409.   register_overcloud_nodes || exit_on_err
  1410.   tag_overcloud_nodes || exit_on_err
  1411.  
  1412.   if [ $DEPLOY_IDM = "yes" ]; then
  1413.     post_idm_config
  1414.   fi
  1415.  
  1416.   echoinfo "All set ! You're good to go !"
  1417.  
  1418.  
  1419. }
  1420.  
  1421. ##########################################################################
  1422. #                                                                        #
  1423. #                              Deploy IDM                                #
  1424. #                                                                        #
  1425. ##########################################################################
  1426.  
  1427. function wait_for_container()
  1428. {
  1429.  
  1430.   local container_name=$1
  1431.   local sleep_t=10       # Sleep interval between tries
  1432.   local max_tries=120     # Max number of tries
  1433.   local nb_tries=0       # Try counter
  1434.   local success=0        # Set to 1 connection worked
  1435.  
  1436.   echoinfo "Waiting for container to be fully configured (20m timeout)..."
  1437. # 5m on a Dell node - 15m on a Cisco node (yay \o/)
  1438.   echoinfo "This process takes approximately 5m on a good standing server."
  1439.  
  1440.   until [ $nb_tries -ge $max_tries ]
  1441.    do
  1442.  
  1443.   if ( docker logs $container_name | tail | grep "FreeIPA server configured" &> /dev/null ); then
  1444.       # This means container is configured sucessfully
  1445.     echoinfo "--- IDM sucessfully configured! ---"
  1446.     success=1
  1447.     break
  1448.   fi
  1449.  
  1450.   if ( docker logs $container_name | tail | grep "FreeIPA server configuration failed" &> /dev/null ); then
  1451.       # This means container configuration failed
  1452.     echoinfo "IDM configuration failed!"
  1453.     break
  1454.   fi
  1455.  
  1456.   nb_tries=$[$nb_tries+1]
  1457.   echo "Try number $nb_tries / $max_tries. Waiting ${sleep_t}s more..."
  1458.   sleep $sleep_t
  1459.  
  1460.   done
  1461.  
  1462.   # Check result
  1463.   if [ $success -eq 0 ]; then
  1464.     return 1
  1465.   else
  1466.     return 0
  1467.   fi
  1468. }
  1469.  
  1470. function idm_deploy()
  1471. {
  1472.  
  1473.   echoinfo "---===== Deploy IDM Container =====---"
  1474.  
  1475.   if [ $DEPLOY_IDM != "yes" ]; then
  1476.     echoinfo "DEPLOY_IDM is set to $DEPLOY_IDM - Skipping deployment!"
  1477.     return 0
  1478.   fi
  1479.   echoinfo "Installing Docker"
  1480.   yum install -y docker ||  { echoerr "Failed to install Docker!"; return 1; }
  1481.  
  1482.   echoinfo "Starting Docker service"
  1483.   sudo systemctl enable --now docker.service  ||  { echoerr "Failed to enable/start docker!"; return 1; }
  1484.  
  1485.   echoinfo "Pulling IDM image from $IDM_IMAGE"
  1486.   docker pull $IDM_IMAGE ||  { echoerr "Failed to pull IDM image from $IDM_IMAGE!"; return 1; }
  1487.  
  1488.   echoinfo "Tagging IDM image"
  1489.   docker tag $IDM_IMAGE idm ||  { echoerr "Failed to tag IDM image $IDM_IMAGE!"; return 1; }
  1490.  
  1491.   echoinfo "Verifying $IDM_BIND_IP is reachable..."
  1492.   ping -c 3 $IDM_BIND_IP || { echoerr "Failed to ping $IDM_BIND_IP!"; return 1; }
  1493.  
  1494.   echoinfo "Configuring firewalld..."
  1495.   firewall-cmd --permanent --add-port={80/tcp,443/tcp,389/tcp,636/tcp,88/tcp,88/udp,464/tcp,464/udp,53/tcp,53/udp,123/udp} || { echoerr "Failed to configure firewalld!"; return 1; }
  1496.   firewall-cmd --permanent --add-service=freeipa-ldap || { echoerr "Failed to configure firewalld"; return 1; }
  1497.   echoinfo "Restarting firewalld..."
  1498.   firewall-cmd --reload || { echoerr "Failed to restart firewalld"; return 1; }
  1499.  
  1500.   echoinfo "Setting up SELinux..."
  1501.   setsebool -P container_manage_cgroup 1
  1502.  
  1503.   echoinfo "Starting IDM container..."
  1504.   # See https://bugzilla.redhat.com/show_bug.cgi?id=1353831
  1505.   docker run -d --restart unless-stopped --net=bridge  -v /var/lib/ipa-data:/data/ipa1/ipa-data \
  1506.     -v /var/log:/data/ipa1/ipa-logs -v /sys/fs/cgroup:/sys/fs/cgroup:ro \
  1507.     -h ipa.redhat.local --tmpfs /run --tmpfs /tmp -e IPA_SERVER_IP=$IDM_BIND_IP  \
  1508.     -p $IDM_BIND_IP:88:88 -p $IDM_BIND_IP:88:88/udp -p $IDM_BIND_IP:123:123/udp \
  1509.     -p $IDM_BIND_IP:389:389 -p $IDM_BIND_IP:443:443 -p $IDM_BIND_IP:464:464 \
  1510.     -p $IDM_BIND_IP:464:464/udp -p $IDM_BIND_IP:636:636 -p $IDM_BIND_IP:7389:7389 \
  1511.     -p $IDM_BIND_IP:9443:9443 -p $IDM_BIND_IP:9444:9444 -p $IDM_BIND_IP:9445:9445 \
  1512.     -p $IDM_BIND_IP:80:80 -p $IDM_BIND_IP:53:53 -p $IDM_BIND_IP:53:53/udp \
  1513.     --name idm -it idm --unattended \
  1514.       --realm=REDHAT.LOCAL \
  1515.       --mkhomedir \
  1516.       --ds-password="redhat42" \
  1517.       --admin-password="redhat42" \
  1518.       --ip-address=$IDM_BIND_IP \
  1519.       --setup-dns \
  1520.       --auto-forwarders \
  1521.       --auto-reverse || { echoerr "Failed to start IDM container!"; return 1; }
  1522.  
  1523. # We need to wait for IDM to be up and running because of DNS (undercloud uses it) and kerberos for novajoin to work properly.
  1524.   wait_for_container idm || { echoerr "IDM container configuration failed! For additional info do a \"docker logs idm\""; return 1; }
  1525.  
  1526. # We need to restart docker for obscure reasons, otherwise overcloud nodes cannot reach container.
  1527.   echoinfo "Restarting docker service..."
  1528.   systemctl restart docker
  1529.  
  1530.   echoinfo "Next steps :"
  1531.   echo "- ssh root@undercloud"
  1532.   echo "- run sh /tmp/osp-lab-deploy.sh undercloud-install as root"
  1533.   echo
  1534.   echo "Happy hacking !!! - The field PM Team"
  1535.  
  1536. }
  1537.  
  1538. ##########################################################################
  1539. #                                                                        #
  1540. #                             Main function                              #
  1541. #                                                                        #
  1542. ##########################################################################
  1543.  
  1544.  
  1545. case $1 in
  1546.   "libvirt-deploy")
  1547.     echoinfo "Starting libvirt deployment..."
  1548.     libvirt_deploy
  1549.    ;;
  1550.   "idm-deploy")
  1551.     echoinfo "Starting IDM container deployment..."
  1552.     idm_deploy || exit_on_err
  1553.   ;;
  1554.   "undercloud-install")
  1555.     echoinfo "Starting undercloud installation..."
  1556.     undercloud_install
  1557.   ;;
  1558.   "overcloud-register")
  1559.     echoinfo "Starting undercloud nodes registration..."
  1560.     overcloud_register
  1561.   ;;
  1562.   "howto")
  1563.     howto
  1564.   ;;
  1565. *)
  1566.   echoerr "Invalid argument"
  1567.   help
  1568.   ;;
  1569. esac
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement