linux_wiki:os_install_post_install

OS Install: Post Install

General Information

After installing an OS via kickstart or a VM Template, there is typically additional standard configuration performed depending upon the environment.

This page demonstrates how to create VM templates and kickstarts that will auto-execute scripts one time for a system's first boot.

Checklist

  • Distro(s): Enterprise Linux 6/7
  • Other: NFS Server sharing a post install configuration script

Firstboot

  • The firstboot script is executed once.
  • It is baked into the system via a VM template or kickstart.
  • It stays generic and calls other external scripts on remote admin systems to do the actual post install configuration.
  • It also reboots the system and sends an email once it has completed

This script is meant to run once and then disable itself. It calls other post install script(s) to do the actual work.

/root/scripts/firstboot.sh

#!/bin/bash
# Name: firstboot.sh
# Description: Auto runs a post install script 1 time
 
#### Customize These Variables ####
nfs_server="10.1.2.3"
nfs_server_share="${nfs_server}:/scripts"
nfs_client_mountpoint="/mnt"
post_install_script="${nfs_client_mountpoint}/scripts/postinstall.sh"
post_install_log="/root/postinstall.log"
 
# Write a successful run file
firstboot_ran_file="/root/.firstboot-ran"
 
# System Admins Group Email
system_admins_email='sysadmins@example.com'
 
# Reboot delay in minutes
reboot_delay="1"
#### End of Customize Variables ####
 
#==============================
# Functions; Main Starts After
#==============================
function check_os_type
{
## Gather Distro and Major Version
  if [ -f /etc/system-release-cpe ];then
    distro=$(awk -F: '{printf "%s", $3}' /etc/system-release-cpe)
    major_version=$(awk -F: '{printf "%d", $5}' /etc/system-release-cpe)
  elif [ -f /etc/redhat-release ];then
    distro=$(awk '{printf "%s", $1}' /etc/redhat-release)
    major_version=$(awk -F. '{print $1}' /etc/redhat-release | awk '{printf "%d", $3}')
  fi
}
 
#====================
# Main Program
#====================
 
echo -e "================================================"
echo -e "####========== Firstboot Script ============####"
echo -e "================================================"
 
# Check to see if script has been run before
if [[ -f ${firstboot_ran_file} ]]; then
  echo -e "\nfirstboot>> Error; First boot ran file detected at: ${firstboot_ran_file}!"
  echo -e "firstboot>> Will NOT execute this script. If you really want to execute, remove that file."
  exit 1
fi
 
# Discover OS Type
check_os_type
 
# Start rpcbind service
if [[ ${major_version} == "7" ]]; then
  systemctl start rpcbind
else
  service rpcbind start
fi
 
# Try to reach the NFS server 3 times
for index in 1 2 3; do
  ping -c 1 ${nfs_server} &> /dev/null
 
  if [[ $? -eq 0 ]]; then
    # Successful ping, exit loop
    break
  else
    # Unsuccessful; wait 10 seconds and try again
    echo -e "firstboot>> Could not reach ${nfs_server}. Sleeping for 10 seconds and will try again."
    sleep 10
  fi
done
 
# Mount script location
echo -e "\nfirstboot>> Mounting script location..."
mount -t nfs ${nfs_server_share} ${nfs_client_mountpoint}
 
# Execute post install script
echo -e "\nfirstboot>> Executing post install script..."
${post_install_script}
 
if [[ $? -eq 0 ]]; then
  echo -e "\nfirstboot>> Post install script successful."
else
  echo -e "\nfirstboot>> Error; Post install script exited with error(s)! Quiting..."
  exit 1
fi
 
#==============================================
# Call other post install scripts/actions here
#==============================================
 
# Unmount nfs share
echo -e "\nfirstboot>> Unmounting nfs share.."
umount ${nfs_client_mountpoint}
 
#### Safeguards to prevent firstboot.sh from running more than once ####
# Create firstboot-ran file
echo -e "\nfirstboot>> Creating firstboot ran file..."
echo -e "firstboot>> firstboot.sh was run on $(date)." > ${firstboot_ran_file}
chown -v root:root ${firstboot_ran_file}
chmod -v 400 ${firstboot_ran_file}
 
# Make script not executable
echo -e "\nfirstboot>> Removing execute permissions on this script..."
chown -v root:root ${0}
chmod -v 400 ${0}
 
# Disable auto execution
if [[ ${major_version} == "7" ]]; then
  systemctl disable firstboot.service
else
  sed -i '/firstboot.sh/d' /etc/rc.d/rc.local
fi
#### End of Safeguards ####
 
# Email notification of completion
echo -e "\nfirstboot>> E-mailing notification that the script completed..."
echo -e "The firstboot script process has completed for: '$(hostname)' on $(date).\n\nThe following actions have successfully run:\n1) Post install script (System updates, General system configuration)\n2) Other scripts\n\nThe system ($(hostname)) will reboot in ${reboot_delay} minute(s).\n\n--- Post Install Errors and Warnings ---\n$(grep ERROR ${post_install_log})\n$(grep WARNING ${post_install_log})" | /bin/mail -s "Firstboot Complete: $(hostname)" ${system_admins_email}
 
# Allow some time for the email to be sent
sleep 5
 
# Reboot system
shutdown -r +${reboot_delay} "firstboot>> Post install script(s) complete. System will be rebooted."

Firstboot will get executed on CentOS 7 via a custom systemd service unit.

Create the following service unit file: /etc/systemd/system/firstboot.service

[Unit]
Description=Auto-execute post install scripts
After=network.target
 
[Service]
ExecStart=/root/scripts/firstboot.sh
 
[Install]
WantedBy=multi-user.target

CentOS 6 will make use of rc.local to execute the script.

Append to: /etc/rc.d/rc.local

/root/scripts/firstboot.sh

Auto Setup

Now that we have a firstboot script and method of executing on boot(CentOS 7 service or CentOS 6 rc.local), the combination of the two can be added to VM templates or kickstarts for unattended execution.


The modifications for auto execution need to be done on a new template that is a modification of your base VM template.

Warning: Do not delete your base template after you have created an auto setup version! If you ever want to update your auto setup template, you will need to deploy from the base template, make changes, and create a new auto setup version.

  • Deploy a new VM from your base template (Create a base template here)
  • Make the following modifications to the new system.
    • CentOS 6
      ## VM deployed from the base template ##
       
      ## Create a script directory for root
      mkdir /root/scripts
       
      ## Mount NFS Server and Copy firstboot.sh to the VM
      mount -t nfs <nfs-server>:/scripts /mnt
      cp -v /mnt/firstboot.sh /root/scripts/
      chown -Rv root:root /root/scripts
      chmod -Rv 700 /root/scripts
       
      ## Create line in rc.local to auto execute firstboot script
      echo "/root/scripts/firstboot.sh" >> /etc/rc.d/rc.local
       
      ## Unmount NFS server
      umount /mnt
    • CentOS 7
      ## VM deployed from the base template ##
       
      ## Create a script directory for root
      mkdir /root/scripts
       
      ## Mount NFS Server and Copy firstboot.sh to the VM
      mount -t nfs <nfs-server>:/scripts /mnt
      cp -v /mnt/firstboot.sh /root/scripts/
      chown -Rv root:root /root/scripts
      chmod -Rv 700 /root/scripts
       
      ## Copy firstboot.service unit to the VM
      cp -v /mnt/firstboot.service /etc/systemd/system/
      chown -v root:root /etc/systemd/system/firstboot.service
      chmod -v 644 /etc/systemd/system/firstboot.service
      systemctl enable firstboot.service
       
      ## Unmount NFS server
      umount /mnt

Kickstart files require a post install section to be edited in order for the firstboot script to be placed on a new system.

  • Modify the “%post” section at the bottom to include the following:
    • CentOS 6
      %post --interpreter /bin/sh --log=root/ks-post.log
      (
       
      ## Start rpcbind for NFS
      service rpcbind start
       
      ## Mount NFS Server
      mount -vt nfs 10.1.2.3:/scripts /mnt
       
      ## Create root's scripts directory
      mkdir /root/scripts
       
      ## Copy the firstboot script to the new directory
      cp -v /mnt/firstboot.sh /root/scripts/
      chown -Rv root:root /root/scripts
      chmod -Rv 700 /root/scripts
       
      ## Create rc.local entry for auto execution on boot
      echo "/root/scripts/firstboot.sh" >> /etc/rc.d/rc.local
       
      ## Unmount NFS Server
      umount -v /mnt
      )
      %end
    • CentOS 7
      %post --interpreter /bin/sh --log=root/ks-post.log
      (
       
      ## Start rpcbind for NFS
      systemctl start rpcbind
       
      ## Mount NFS Server
      mount -vt nfs 10.1.2.3:/scripts /mnt
       
      ## Create root's scripts directory
      mkdir /root/scripts
       
      ## Copy the firstboot script to the new directory
      cp -v /mnt/firstboot.sh /root/scripts/
      chown -Rv root:root /root/scripts
      chmod -Rv 700 /root/scripts
       
      ## Copy the firstboot service for auto execution on boot
      cp -v /mnt/firstboot.service /etc/systemd/system/
      chown -v root:root /etc/systemd/system/firstboot.service
      chmod -v 644 /etc/systemd/system/firstboot.service
       
      ## Enable firstboot service
      systemctl enable firstboot.service
       
      ## Unmount NFS Server
      umount -v /mnt
      )
      %end

Post Install Script

  • The post install script is what gets called via the firstboot script.
  • This script does all the heavy lifting (system updates, configuration, etc).

Post Install Script: Parent

Post install script: Provide logging and error checking

postinstall.sh
#!/bin/bash
# Title: postinstall.sh
# Description: Wrapper script to start the postinstall_worker.sh script with logging.
# Last Updated: 2016-10-24
# Most Recent Changes:-Initial release
#######################################################################################
 
function print_usage
{
echo
echo " Usage: postinstall.sh [-y]"
echo
echo "   This script(${0}), provides logging for its worker script, worker_postinstall.sh"
echo
echo "   Recommended action"
echo "   1) Mount: mount -t nfs nfs-server:/admin /mnt"
echo "   2) Execute parent script: /mnt/deploy/postinstall.sh [-y]"
echo "      -y  => Yes, execute script without prompting."
echo
exit 1
}
 
#=====================================
# Get Script Arguments
#=====================================
# Reset POSIX variable in case it has been used previously in this shell
OPTIND=1
 
# By default, do not force run script. Prompt for running or not.
force_run_script="no"
 
while getopts "hy" opt; do
  case "${opt}" in
    h) # -h (help) argument
      print_usage
      exit 0
    ;;
    y) # -y (yes to running script) argument
      force_run_script="yes"
    ;;
    *) # invalid argument
      print_usage
      exit 0
    ;;
  esac
done
 
##====================
## Pre-req checks
##====================
 
## Ensure we are root ##
if [[ $(id --user) -ne 0 ]]; then
  echo ">>Error; this script must be run as root. Exiting..."
  exit 1
fi
 
##======================
## Set Script Variables
##======================
 
# Set base path from executed command (relative or full path works)
base_path="$(echo ${0} | sed 's/postinstall.sh//')"
 
# Set log file and script locations
postinstall_log="/root/postinstall.log"
postinstall_worker="worker_postinstall.sh"
 
##================
## Setup Logging
##================
echo -e ">>Logging output and errors to: ${postinstall_log}\n"
 
# Clear log and timestamp the beginning
cat /dev/null > ${postinstall_log}
echo -e "---- Log Started: $(date) ----\n" >> ${postinstall_log}
 
##=========================
## Execute External Scripts
##=========================
# Start script, pass base path argument
if [[ ${force_run_script} == "no" ]]; then
  ${base_path}${postinstall_worker} -d ${base_path} 2>&1 | tee -a ${postinstall_log}
elif [[ ${force_run_script} == "yes" ]]; then
  ${base_path}${postinstall_worker} -d ${base_path} -y 2>&1 | tee -a ${postinstall_log}
else
  echo -e ">>Error: Unknown value for force_run_script (${force_run_script}). Exiting..."
  exit 1
fi
 
##==========================
## Close Logs, Show Location
##==========================
# Ending timestamp
echo -e "\n---- Log Completed: $(date) ----" >> ${postinstall_log}
 
# Reminder of where the log file is at
echo -e "\n>>Logged output and errors were sent to: ${postinstall_log}\n"
echo -e "----> Remember to umount NFS before rebooting <----"

Post Install Script: Worker

Post install worker: Perform the actual installations/config work

worker_postinstall.sh
#!/bin/bash
# Name: worker_postinstall.sh
# Description: Post-install configuration worker script for Enterprise Linux 6/7
#              This script is meant to be launched via its parent script: postinstall.sh
# Last Updated: 2016-12-14
# Recent Changes:-Fixed services section for EL7; 1 failed service no longer affects others.
#                -Clamd install/config. Removed fallback for freshclam files. Updated services
#                section to be EL7 or other specific for target services.
###############################################################################################
 
function print_usage
{
echo
echo " Usage: postinstall.sh [-y]"
echo
echo "   This script(${0}), is a worker script that is meant to be launched"
echo "   from the parent script: postinstall.sh."
echo
echo "   Recommended action"
echo "   1) Mount: mount -t nfs nfs-server:/admin /mnt"
echo "   2) Execute parent script: /mnt/deploy/postinstall.sh [-y]"
echo "      -y  => Yes, execute script without prompting."
echo
exit 1
}
 
function get_os_type
{
if [ -f /etc/system-release-cpe ];then
  distro=$(awk -F: '{printf "%s", $3}' /etc/system-release-cpe)
  major_version=$(awk -F: '{printf "%d", $5}' /etc/system-release-cpe)
elif [ -f /etc/redhat-release ];then
  distro=$(awk '{printf "%s", $1}' /etc/redhat-release)
  major_version=$(awk -F. '{print $1}' /etc/redhat-release | awk '{printf "%d", $3}')
fi
 
# ${distro,,} converts to lower case for comparison
if [[ ${distro,,} == "centos" || ${distro,,} == "oracle" ]]; then
  case $major_version in
    7)
      OSTYPE="el7"
    ;;
    6)
      OSTYPE="el6"
    ;;
    5)
      echo ">>Error: ${distro} ${major_version} is deprecated."
      exit 1
    ;;
    *)
      echo ">>Error: Cannot determine ${distro} major version or version not supported (${major_version})."
      exit 1
    ;;
  esac
else
  echo ">>Error: Only CentOS and Oracle Linux are supported...exiting."
  exit 1
fi
}
 
#=====================================
# Get Script Arguments
#=====================================
# Reset POSIX variable in case it has been used previously in this shell
OPTIND=1
 
# By default, do not force run script. Prompt for running or not.
force_run_script="no"
 
while getopts "hd:y" opt; do
  case "${opt}" in
    h) # -h (help) argument
      print_usage
      exit 0
    ;;
    d) # -d (directory path)
      base_path=${OPTARG}
    ;;
    y) # -y (yes to running script) argument
      force_run_script="yes"
    ;;
    *) # invalid argument
      print_usage
      exit 0
    ;;
  esac
done
 
####==================================
#### Main Starts Here
####==================================
 
# Ensure a base path of where we start is passed
if [ ! -d "${base_path}" ]; then
  echo ">>Error: Argument -d 'dir' expected and must be a directory."
  print_usage
fi
 
# Set variables used throughout the script
get_os_type
 
#====================================================================
# Confirm running the post install script
#====================================================================
echo -e "======================================================"
echo -e "####========= Post Install Configuration =========####"
echo -e "======================================================"
echo
echo -e "Warning: Run this on a fresh install only for initial setup."
echo -e "Detected Distro: ${distro} ${major_version}"
echo -e "OS Family: ${OSTYPE}"
echo -e "Using Base Path: ${base_path}"
echo -e "=>Continue?[y/n]:\c"
 
if [[ ${force_run_script} == "no" ]]; then
  read run_script
elif [[ ${force_run_script} == "yes" ]]; then
  echo -e " Force run script detected. Continuing..."
  run_script="y"
else
  echo -e ">>Error: Unknown value for force_run_script (${force_run_script}). Exiting..."
  exit 1
fi
 
if [[ ${run_script} != "y" ]]; then
  echo -e "\n>>Will not run the post install script. Exiting..."
  exit 1
fi
 
#===================================================================
# Remove some packages
#===================================================================
echo -e "\n\n>>Removing some packages..."
 
# If a Virtual Machine: Remove/Disable biosdevname so network device naming
# doesn't change to port/slot naming convention
dmidecode | grep -i vmware > /dev/null
if [[ $? -eq 0 ]]; then
 
  echo -e "\n->Checking for biosdevname..."
  rpm -q biosdevname
 
  if [ $? -eq 0 ]; then
    echo -e "->Removing biosdevname..."
    yum -y remove biosdevname
 
    # Disable the kernel option for biosdevname
    if [[ ${major_version} == "7" ]]; then
      # check for "net.ifnames=0 biosdevname=0" on the kernel options line
      if [[ $(grep GRUB_CMDLINE_LINUX /etc/default/grub | grep -o "net.ifnames=0 biosdevname=0" | wc -l) -eq 0 ]]; then
        echo -e "->Disabling biosdevname kernel option..."
        # remove trailing quote (") and then append: net.ifnames=0 biosdevname=0"
        sed -i -r -e "/^GRUB_CMDLINE_LINUX/s/\"$//" /etc/default/grub
        sed -i -r -e "/^GRUB_CMDLINE_LINUX/s/^(GRUB_CMDLINE_LINUX=\".*)/\1 net.ifnames=0 biosdevname=0\"/g" /etc/default/grub
        grub2-mkconfig -o /boot/grub2/grub.cfg
      fi
    else
      echo -e "->Disabling biosdevname kernel option..."
      # append biosdevname=0 to the kernel lines
      sed -i -r -e "/^\s+kernel/s/^(\s+kernel .*)/\1 biosdevname=0/g" /boot/grub/grub.conf
    fi
  fi
fi
## End of virtual machine check ##
 
# Space separated list of packages to remove
remove_packages="NetworkManager abrt setroubleshoot-server"
 
# Remove the packages
for package in ${remove_packages}; do
  echo -e "\n->Checking for ${package}..."
  rpm -q ${package}
  if [ $? -eq 0 ]; then
    echo -e "->Removing ${package}..."
    yum -y remove ${package}
  fi
done
 
#====================================================================
# Temporary DNS Settings
#====================================================================
echo -e "\n\n>>Setting temporary DNS settings to ensure a working config..."
 
echo "##== Temp Settings from worker_postinstall.sh ==##" > /etc/resolv.conf
echo "search example.com" >> /etc/resolv.conf
echo "options timeout:1" >> /etc/resolv.conf
echo "options attempts:1" >> /etc/resolv.conf
echo "nameserver ip.address.here" >> /etc/resolv.conf
echo "nameserver ip.address.here" >> /etc/resolv.conf
echo "nameserver ip.address.here" >> /etc/resolv.conf
 
echo -e "->Settings are:"
cat /etc/resolv.conf
 
echo -e "\n>>Removing interface DNS over rides..."
sed -i '/^DNS.*/d' /etc/sysconfig/network-scripts/ifcfg-*
 
#====================================================================
# Register with Spacewalk - or other systems management app
#====================================================================
 
#=========================
# Spacewalk Customization
#=========================
 
# Spacewalk server fqdn hostname
sw_server="spacewalk.example.com"
 
# Spacewalk server's ssl ca rpm version and installed location
#(this is the package available at: https://${sw_server}/pub/${sw_server_ca})
sw_server_ca="rhn-org-trusted-ssl-cert-1.0-1.noarch.rpm"
sw_server_ca_installed="/usr/share/rhn/RHN-ORG-TRUSTED-SSL-CERT"
 
# Spacewalk server channel activation keys
sw_activation_key_centos6_32bit="1-centos6_i386_key"
sw_activation_key_centos6_64bit="1-centos6_x86-64_key"
sw_activation_key_centos7_64bit="1-centos7_x86-64_key"
sw_activation_key_oracle6_64bit="1-oracle6_x86-64_key"
sw_activation_key_oracle7_64bit="1-oracle7_x86-64_key"
 
# Repos and GPG Keys
sw_client_repo_gpgkey="http://${sw_server}/pub/repos/RPM-GPG-KEY-spacewalk-2015"
sw_client_repo_el6="http://${sw_server}/pub/repos/spacewalk-client-repo-2.4-3.el6.noarch.rpm"
sw_client_repo_el7="http://${sw_server}/pub/repos/spacewalk-client-repo-2.4-3.el7.noarch.rpm"
 
sw_epel_repo_el6_gpgkey="http://${sw_server}/pub/repos/RPM-GPG-KEY-EPEL-6"
sw_epel_repo_el7_gpgkey="http://${sw_server}/pub/repos/RPM-GPG-KEY-EPEL-7"
sw_epel_repo_el6="http://${sw_server}/pub/repos/epel-release-latest-6.noarch.rpm"
sw_epel_repo_el7="http://${sw_server}/pub/repos/epel-release-latest-7.noarch.rpm"
 
#======================
# End of Customization
#======================
 
echo -e "\n\n>>Registering with Spacewalk..."
 
## Pre-Register Checks ##
echo -e "\n->Performing pre-registration system checks..."
 
#Store system architecture so we aren't calling uname multiple times
system_arch=$(uname -i)
 
if [[ ${system_arch} != "x86_64" && ${system_arch} != "i386" ]]; then
  echo -e "->Error: Only x86_64 or i386 architecture channels supported at this time."
  register_with_spacewalk="no"
else
  if [[ ${distro,,} == "centos" ]]; then
    case $major_version in
      7)
        ## CentOS 7 Register - Set spacewalk client repo, epel, activation key ##
        if [[ ${system_arch} != "x86_64" ]]; then
          echo -e "->Error: Only ${distro} ${major_version} x86_64 architecture channels supported at this time."
          register_with_spacewalk="no"
        else
          sw_client_repo="${sw_client_repo_el7}"
          sw_epel_repo="${sw_epel_repo_el7}"
          sw_epel_repo_gpgkey="${sw_epel_repo_el7_gpgkey}"
          sw_activation_key="${sw_activation_key_centos7_64bit}"
          register_with_spacewalk="yes"
        fi
      ;;
      6)
        ## CentOS 6 Register - Set spacewalk client repo, epel, activation key ##
        sw_client_repo="${sw_client_repo_el6}"
        sw_epel_repo="${sw_epel_repo_el6}"
        sw_epel_repo_gpgkey="${sw_epel_repo_el6_gpgkey}"
 
        if [[ ${system_arch} == "x86_64" ]]; then
          sw_activation_key="${sw_activation_key_centos6_64bit}"
        else
          sw_activation_key="${sw_activation_key_centos6_32bit}"
        fi
        register_with_spacewalk="yes"
      ;;
      *)
        echo "-> Warning: No Spacewalk channel available for ${distro} ${major_version}."
        register_with_spacewalk="no"
      ;;
    esac
  elif [[ ${distro,,} == "oracle" ]]; then
    case ${major_version} in
      7)
        # Oracle 7 register - Set spacewalk client repo, epel, activation key ##
        if [[ ${system_arch} != "x86_64" ]]; then
          echo -e "->Error: Only ${distro} ${major_version} x86_64 architecture channels supported at this time."
          register_with_spacewalk="no"
        else
          sw_client_repo="${sw_client_repo_el7}"
          sw_epel_repo="${sw_epel_repo_el7}"
          sw_epel_repo_gpgkey="${sw_epel_repo_el7_gpgkey}"
          sw_activation_key="${sw_activation_key_oracle7_64bit}"
          register_with_spacewalk="yes"
        fi
      ;;
      6)
        ## Oracle 6 register - Set spacewalk client repo, epel, activation key ##
        if [[ ${system_arch} != "x86_64" ]]; then
          echo -e "->Error: Only ${distro} ${major_version} x86_64 architecture channels supported at this time."
          register_with_spacewalk="no"
        else
          sw_client_repo="${sw_client_repo_el6}"
          sw_epel_repo="${sw_epel_repo_el6}"
          sw_epel_repo_gpgkey="${sw_epel_repo_el6_gpgkey}"
          sw_activation_key="${sw_activation_key_oracle6_64bit}"
          register_with_spacewalk="yes"
        fi
      ;;
      *)
        echo "-> Warning: No Spacewalk channel available for ${distro} ${major_version}."
        register_with_spacewalk="no"
      ;;
    esac
  else
    echo -e "-> Warning: ${distro} not supported. Only CentOS and Oracle channels available at this time."
    register_with_spacewalk="no"
  fi # end of distro == centos, elif oracle check
fi # end of architecture check
 
## Begin Registration Process ##
if [[ ${register_with_spacewalk} == "yes" ]]; then
  # Add Repos #
  echo -e "\n->Adding Spacewalk Client Repo..."
  rpm -v --import ${sw_client_repo_gpgkey}
  rpm -ivh ${sw_client_repo}
 
  echo -e "\n->Adding EPEL Repo..."
  rpm -v --import ${sw_epel_repo_gpgkey}
  rpm -ivh ${sw_epel_repo}
 
  echo -e "\n->Making yum cache..."
  yum makecache fast
 
  # Install Spacewalk's CA Cert #
  echo -e "\n>> Installing ${sw_server}'s trusted CA cert..."
  rpm -ivh https://${sw_server}/pub/${sw_server_ca}
 
  echo -e "\n->Caching DNS lookup for mirrors.fedoraproject.org..."
  dig mirrors.fedoraproject.org &> /dev/null
 
  # Install Client Packages
  echo -e "\n->Installing rhn client packages..."
  yum -y install rhn-client-tools rhn-check rhn-setup rhnsd m2crypto yum-rhn-plugin
 
  # Register #
  echo -e "\n>> Registering with ${sw_server}..."
  rhnreg_ks --serverUrl=https://${sw_server}/XMLRPC --sslCACert=${sw_server_ca_installed} --activationkey=${sw_activation_key}
  registration_return_code=$?
 
  if [[ ${registration_return_code} -eq 0 ]]; then
    echo -e "->Registration successful."
    sw_registered="yes"
 
    # Show website
    echo -e "->System should now appear in the Spacewalk portal at: https://${sw_server}/rhn/systems/Registered.do"
    sleep 2
 
    # Install Config Management Packages
    echo -e "\n->Installing rhn configuration management client packages..."
    yum -y install rhncfg rhncfg-actions rhncfg-client rhncfg-management
 
    # Allow Spacewalk server to deploy config files
    echo -e "\n->Enabling Spacewalk server deploy control..."
    rhn-actions-control --enable-all
 
    # Deploy spacewalk-checkin cron job (runs rhn_check every 30 mins)
    echo -e "\n>> Deploying /etc/cron.d/spacewalk-checkin job..."
    rhncfg-client get /etc/cron.d/spacewalk-checkin
 
    # If not successful, create a minimum job file
    grep --quiet "This Config Managed by Spacewalk" /etc/cron.d/spacewalk-checkin
    if [[ $? -ne 0 ]]; then
      echo "# Spacewalk - Check in to the Spacewalk Server via rhn_check" > /etc/cron.d/spacewalk-checkin
      echo 'MAILTO=""' >> /etc/cron.d/spacewalk-checkin
      echo "*/30 * * * * root /usr/sbin/rhn_check" >> /etc/cron.d/spacewalk-checkin
 
      echo -e "\n>> Setting permissions on /etc/cron.d/spacewalk-checkin..."
      chmod -v 600 /etc/cron.d/spacewalk-checkin
    fi
 
    ## Disable rhnsd (not needed because of cron job "spacewalk-checkin" ##
    echo -e "\n>> Disabling rhnsd(not needed because of cron job 'spacewalk-checkin'..."
    if [[ ${major_version} == "7" ]]; then
      systemctl disable rhnsd
      systemctl stop rhnsd
    else
      chkconfig rhnsd off
      service rhnsd stop
    fi
 
    ## Add Custom GPG Key - If you created a custom Repo on Spacewalk ##
    sw_custom_repo_gpgkey="http://${sw_server}/pub/repos/RPM-GPG-KEY-Custom"
    echo -e "\n>> Adding Custom GPG key from: ${sw_custom_repo_gpgkey}"
    rpm -v --import ${sw_custom_repo_gpgkey}
 
    ## Deploy Config Files - If you are managing config files on Spacewalk ##
 
    echo -e "\n->Deploying OS specific config files..."
    for FILE in $(rhncfg-client list | awk /el${major_version}-os/'{print $3}'); do
      rhncfg-client get ${FILE}
    done
 
    echo -e "\n->Deploying Base config files..."
    for FILE in $(rhncfg-client list | awk /base/'{print $3}'); do
      rhncfg-client get ${FILE}
    done
 
 
    ## Disable Old Repos ##
    if [[ ${distro,,} == "centos" ]]; then
      # Disable CentOS default system repos
      echo -e "\n->Disabling default CentOS repos..."
      for FILE in /etc/yum.repos.d/CentOS-*.repo; do
        sed -i 's/enabled=1/enabled=0/' ${FILE}
        sed -i '/gpgcheck/a enabled=0' ${FILE}
      done
    elif [[ ${distro,,} == "oracle" ]]; then
      # Disable Oracle default system repos
      echo -e "\n-> Disabling default Oracle repos..."
      for FILE in /etc/yum.repos.d/public-yum-ol*.repo; do
        sed -i 's/enabled=1/enabled=0/' ${FILE}
        sed -i '/gpgcheck/a enabled=0' ${FILE}
      done
    fi
 
    # Disable temporary epel repo
    echo -e "\n->Disabling default epel repos..."
    sed -i 's/enabled=1/enabled=0/' /etc/yum.repos.d/epel.repo
    sed -i 's/enabled=1/enabled=0/' /etc/yum.repos.d/epel-testing.repo
 
    # Show repos
    echo -e "\n->Active repos are:"
    yum repolist
 
  elif [[ ${registration_return_code} -eq 255 ]]; then
    echo -e "-> Registration encountered an error! (Return Code: ${registration_return_code})"
    echo -e "\n-> To manually force registration(if that is the problem), copy/paste: rhnreg_ks --force --serverUrl=https://${sw_server}/XMLRPC --sslCACert=${sw_server_ca_installed} --activationkey=${sw_activation_key}"
    echo -e "\n--> WARNING: This may create duplicate systems in Spacewalk."
    echo -e "\n-> Once registered, manually complete the rest of the process: rhn-actions-control --enable-all; rhncfg-client get /etc/cron.d/spacewalk-checkin"
    echo -e "-> Then disable non Base,Extra,Updates,and EPEL repos."
    sw_registered="no"
 
  else
    # Registration was not successful
    echo -e "-> Registration encountered an error! (Return Code: ${registration_return_code})"
    echo -e "-> Will NOT install setup spacewalk-checkin job and disable default repos."
    sw_registered="no"
  fi
 
else
  echo -e "-> WARNING: Will NOT register system with Spacewalk."
  sw_registered="no"
fi
## End Registration Process ##
 
#====================================================================
# Install system packages
#====================================================================
echo -e "\n\n>>Ensuring base system packages are installed..."
yum -y install bash-completion bind-utils dmidecode iotop lsof mailx man mlocate nfs-utils openssh-clients perl psmisc rsync tcpdump vim-enhanced wget yum-utils
 
echo -e "\n->Ensuring man pages are up to date..."
if [[ ${major_version} == "7" ]]; then
  mandb
else
  makewhatis
fi
 
echo -e "\n->Ensure lastlog exists..."
touch /var/log/lastlog
 
#====================================================================
# Configure Grub
#====================================================================
echo -e "\n\n>>Configuring Grub..."
 
echo -e "\n->Setting grub timeout to 3..."
if [[ ${major_version} == "7" ]]; then
  sed -i 's/^GRUB_TIMEOUT=[0-9]*/GRUB_TIMEOUT=3/' /etc/default/grub
else
  sed -i 's/^timeout=[0-9]*/timeout=3/' /boot/grub/grub.conf
fi
 
echo -e "\n->Removing 'hiddenmenu'..."
if [[ ${major_version} == "7" ]]; then
  echo -e "->Nothing to do for EL 7."
else
  sed -i '/hiddenmenu/d' /boot/grub/grub.conf
fi
 
echo -e "\n->No picture while booting..."
if [[ ${major_version} == "7" ]]; then
  sed -i 's/ rhgb//g' /etc/default/grub
else
  sed -i 's/ rhgb//g' /boot/grub/grub.conf
fi
 
echo -e "\n->No 'quiet' booting..."
if [[ ${major_version} == "7" ]]; then
  sed -i 's/ quiet//g' /etc/default/grub
else
  sed -i 's/ quiet//g' /boot/grub/grub.conf
fi
 
if [[ ${major_version} == "7" ]]; then
  echo -e "\n->Generating grub config..."
  grub2-mkconfig -o /boot/grub2/grub.cfg
fi
 
#====================================================================
# Install and configure time protocol
#====================================================================
echo -e "\n\n>>Installing and configuring time protocol..."
 
if [[ ${major_version} == "7" ]]; then
  echo -e "\n->Removing NTP, installing Chrony..."
  yum -y remove ntp
  yum -y install chrony
  time_config="chrony.conf"
else
  echo -e "\n->Installing NTP..."
  yum -y install ntp
  time_config="ntp.conf"
fi
 
echo -e "\n->Initial time sync..."
if [[ ${major_version} == "7" ]]; then
  echo -e "->Chrony automatically syncs time upon startup quickly; do nothing here."
else
  ntpd -gxq
  sleep 1
  ntpd -gxq
  sleep 1
  ntpd -gxq
  sleep 1
fi
 
echo -e "\n->Starting and enabling the time service..."
if [[ ${major_version} == "7" ]]; then
  systemctl restart chronyd
  systemctl enable chronyd
else
  service ntpd restart
  chkconfig ntpd on
fi
 
#====================================================================
# System Updates
#====================================================================
echo -e "\n\n>>Running system updates..."
yum -y update
 
#====================================================================
# Configure OS settings
#====================================================================
echo -e "\n\n>>Configuring OS settings..."
 
# Not in Spacewalk Config Channels
echo -e "\n->Non-Spacewalk Managed configs (remove motd, at.allow, cron.allow)..."
rm -fv /etc/motd
\cp -v ${base_path}os-agnostic/etc/at.allow /etc/at.allow
\cp -v ${base_path}os-agnostic/etc/cron.allow /etc/cron.allow
 
# Ensure proper ownership and permissions
chown -v root:root /etc/at.allow /etc/cron.allow
chmod -v 600 /etc/at.allow /etc/cron.allow
 
#====================================================================
# Setup Mail
#====================================================================
echo -e "\n\n>>Configuring mail..."
 
# Setup alias for root's mail
mail_aliases='root: sysadmins@example.com'
echo -e "\n->Setting the following root alias in /etc/aliases: ${mail_aliases}"
sed -i -r -e "s/^#?root.*/${mail_aliases}/" /etc/aliases
 
echo -e "\n->Rebuilding aliases.db..."
newaliases
 
# Determine if using postfix or sendmail, setup config
echo -e "\n->Checking for postfix and sendmail packages..."
rpm -q postfix
postfix_installed="$?"
rpm -q sendmail
sendmail_installed="$?"
 
if [[ ${postfix_installed} -eq 0 ]]; then
  mail_client="postfix"
  echo -e "\n->Detected mail client is: ${mail_client}. Configuring..."
 
elif [[ ${sendmail_installed} -eq 0 ]]; then
  mail_client="sendmail"
  echo -e "\n->Detected mail client is: ${mail_client}. Configuring..."
 
else
  mail_client=""
  echo -e "\n>>Error! Could not detect an installed postfix or sendmail config."
fi
 
if [[ ${mail_client} == "postfix" || ${mail_client} == "sendmail" ]]; then
  echo -e "\n->Starting up mail client: ${mail_client}..."
 
  if [[ ${major_version} == "7" ]]; then
    systemctl start ${mail_client}
    systemctl enable ${mail_client}
  else
    service ${mail_client} start
    chkconfig ${mail_client} on
  fi
fi
 
#====================================================================
# Setup Authentication (IPA) - or other LDAP source
#====================================================================
echo -e "\n\n>>Configuring Authentication(IPA)..."
 
echo -e "\n->Installing IPA Client packages..."
yum -y install ipa-client
 
case ${OSTYPE} in
  "el7") # EL7 IPA Config
 
    # Unattended install
    echo -e "\n->Running IPA Unattended realm join..."
    ipa-client-install --domain=example.com --server=ipaserver01.example.com --server=ipaserver02.example.com --mkhomedir --no-dns-sshfp --fixed-primary --hostname=$(hostname | sed 's/.example.com//' | tr '[:upper:]' '[:lower:]').example.com --no-ntp --principal autoenroll --password=<PASSWORD-HERE> --unattended --force-join
 
    if [[ $? -ne 0 ]]; then
      # ipa-client-install exited with a non-zero status
      echo -e "->ERROR! ipa-client-install encountered an error! Is the host added to the IPA servers?"
      echo -e "->WARNING: System not joined to IPA."
    else
      # ipa-client-install realm join was successful
 
      # fix sshd config: ipa-client-install modifies sshd, breaking it if there are any Match statements
      echo -e "\n->Redeploying sshd config and restart the service..."
      rhncfg-client get /etc/ssh/sshd_config
      systemctl restart sshd
 
      echo -e "\n->Ensuring nscd/nslcd is disabled..."
      systemctl stop nslcd nscd
      systemctl disable nslcd nscd
 
      echo -e "\n->Disabling ldap identification,ldap auth, and force legacy (sssd used instead)..."
      authconfig --disableldap --disableldapauth --disableforcelegacy --update
 
      echo -e "\n->Restarting sssd..."
      systemctl restart sssd
 
      echo -e "\n->Starting and enabling oddjobd..."
      systemctl start oddjobd
      systemctl enable oddjobd
    fi
 
  ;; # END of EL7 IPA Config
 
  "el6") # EL6 IPA Config
 
    # Unattended install
    echo -e "\n->Running IPA Unattended realm join..."
    ipa-client-install --domain=example.com --server=ipaserver02.example.com --server=ipaserver01.example.com --mkhomedir --no-dns-sshfp --fixed-primary --hostname=$(hostname | sed 's/.example.com//' | tr '[:upper:]' '[:lower:]').example.com --no-ntp --principal autoenroll --password=<PASSWORD-HERE> --unattended --force-join
 
    if [[ $? -ne 0 ]]; then
      # ipa-client-install exited with a non-zero status
      echo -e "->ERROR! ipa-client-install encountered an error! Is the host added to the IPA servers?"
      echo -e "->WARNING: System not joined to IPA."
    else
      # ipa-client-install realm join was successful
 
      # fix sshd config: ipa-client-install modifies sshd, breaking it if there are any Match statements
      echo -e "\n->Redeploying sshd config and restart the service..."
      rhncfg-client get /etc/ssh/sshd_config
      service sshd restart
 
      echo -e "\n->Ensuring nscd/nslcd is disabled..."
      service nslcd stop
      service nscd stop
      chkconfig nslcd off
      chkconfig nscd off
 
      echo -e "\n->Disabling ldap identification,ldap auth, and force legacy (sssd used instead)..."
      authconfig --disableldap --disableldapauth --disableforcelegacy --update
 
      echo -e "\n->Restarting sssd..."
      service sssd restart
 
      echo -e "\n->Starting and enabling oddjobd..."
      service messagebus start
      service oddjobd start
      chkconfig messagebus on
      chkconfig oddjobd on
 
      echo -e "\n->Adding client idle timeout to sssd.conf (cron fix for EL6 bug)..."
      if [[ $(grep client_idle_timeout /etc/sssd/sssd.conf) ]]; then
        echo -e "->Client idle timeout found in sssd.conf, will not append"
      else
        sed -i '/services = nss, sudo, pam, ssh/ a\client_idle_timeout=75' /etc/sssd/sssd.conf
        service sssd restart
        service crond restart
      fi
 
    fi
 
  ;; # END of EL6 IPA Config
 
esac
 
#====================================================================
# Setup monitoring client
#====================================================================
 
# Install and configure system monitoring client here
 
#====================================================================
# Install Extra System Packages, EPEL Repo, and EPEL Packages
#====================================================================
echo -e "\n\n>>Installing extra packages..."
 
# Space separated package list
SYS_PKGS="sysstat"
echo -e "\n->Installing extra system packages: ${SYS_PKGS}"
yum -y install ${SYS_PKGS}
 
# Check to see if Spacewalk has registered the EPEL repo
echo -e "\n->Checking for Spacewalk EPEL repo..."
yum repolist | grep ".*_epel"
epel_added="$?"
 
if [[ ${epel_added} -eq 0 ]]; then
  # EPEL repo was found in yum repolist
  echo -e "\n->EPEL repo detected. Will not add again."
else
  # EPEL repo was NOT found in yum repolist; Add EPEL Repo
  echo -e "\n->EPEL repo not found; Adding EPEL repo..."
  yum -y install epel-release
 
  echo -e "\n->Caching mirrors.fedoraproject.org with dig...\n"
  dig mirrors.fedoraproject.org > /dev/null
 
  echo -e "\n->Listing repos to build cache..."
  yum repolist
  if [ $? -eq 1 ]; then
    echo -e "\n->Repo list error...attempting to fix."
    yum clean all
 
    yum repolist
    if [ $? -eq 1 ]; then
      echo -e "\n->STILL repolist error...probably because of EPEL. Trying to reinstall..."
      yum -y remove epel-release
      yum clean all
      yum -y install epel-release
 
      echo -e "\n->Caching mirrors.fedoraproject.org with dig...\n"
      dig mirrors.fedoraproject.org > /dev/null
      echo -e "\n->Listing repos to build cache..."
      yum repolist
    fi
  fi
fi # end of yum repolist grep
 
# Space separated package list
EPEL_PKGS="clamav clamav-update iperf"
echo -e "\n->Installing EPEL packages: ${EPEL_PKGS}"
yum -y install ${EPEL_PKGS}
 
#====================================================================
# Configure Extra Packages
#====================================================================
echo -e "\n\n>>Configuring extra packages..."
 
echo -e "\n->Removing 'REMOVE ME' lines from /etc/sysconfig/freshclam..."
if [[ -f /etc/sysconfig/freshclam ]]; then
  sed -i '/REMOVE ME/d' /etc/sysconfig/freshclam
else
  echo -e "->Skipping => /etc/sysconfig/freshclam does not exist."
fi
 
#====================================================================
# System Services --- Startup
#====================================================================
echo -e "\n\n>>Starting some services..."
 
# Space separated services list
SERVICES_START="auditd clamd"
SERVICES_START_EL7="auditd clamd@scan"
 
if [[ ${major_version} == "7" ]]; then
  echo -e "\n->Attempting to start: ${SERVICES_START_EL7}"
  for SYSTEM_SERVICE in ${SERVICES_START_EL7}; do
    systemctl start ${SYSTEM_SERVICE}
  done
else
  echo -e "\n->Attempting to start: ${SERVICES_START}"
  for SYSTEM_SERVICE in ${SERVICES_START}; do
    service ${SYSTEM_SERVICE} start
  done
fi
 
#====================================================================
# System Services --- Enable on boot
#====================================================================
echo -e "\n\n>>Enabling some services..."
 
# Space separated services list
SERVICES_ON="auditd clamd oddjobd ${mail_client}"
SERVICES_ON_EL7="auditd clamd@scan oddjobd ${mail_client}"
 
if [[ ${major_version} == "7" ]]; then
  echo -e "\n->Attempting to enable: ${SERVICES_ON_EL7}"
  for SYSTEM_SERVICE in ${SERVICES_ON_EL7}; do
    systemctl enable ${SYSTEM_SERVICE}
  done
else
  echo -e "\n->Attempting to enable: ${SERVICES_ON}"
  for SYSTEM_SERVICE in ${SERVICES_ON}; do
    chkconfig ${SYSTEM_SERVICE} on
  done
fi
 
#====================================================================
# System Services --- Stop
#====================================================================
echo -e "\n\n>>Stopping some services..."
 
# Space separated services list
SERVICES_STOP="kdump saslauthd"
SERVICES_STOP_EL7="kdump saslauthd"
 
if [[ ${major_version} == "7" ]]; then
  echo -e "\n->Attempting to stop: ${SERVICES_STOP_EL7}"
  for SYSTEM_SERVICE in ${SERVICES_STOP_EL7}; do
    systemctl stop ${SYSTEM_SERVICE}
  done
else
  echo -e "\n->Attempting to stop: ${SERVICES_STOP}"
  for SYSTEM_SERVICE in ${SERVICES_STOP}; do
    service ${SYSTEM_SERVICE} stop
  done
fi
 
#====================================================================
# System Services --- Disable
#====================================================================
echo -e "\n\n>>Disabling some services..."
 
# Space separated services list
SERVICES_OFF="kdump saslauthd"
SERVICES_OFF_EL7="kdump saslauthd"
 
if [[ ${major_version} == "7" ]]; then
  echo -e "\n->Attempting to disable: ${SERVICES_OFF_EL7}"
  for SYSTEM_SERVICE in ${SERVICES_OFF_EL7}; do
    systemctl disable ${SYSTEM_SERVICE}
  done
else
  echo -e "\n->Attempting to disable: ${SERVICES_OFF}"
  for SYSTEM_SERVICE in ${SERVICES_OFF}; do
    chkconfig ${SYSTEM_SERVICE} off
  done
fi
 
#====================================================================
# Post Installation Completed
#====================================================================
echo -e "\n\n#=================================================================="
echo "# Post Install Configuration Completed. - A reboot is recommended."
echo "#=================================================================="
exit 0

  • linux_wiki/os_install_post_install.txt
  • Last modified: 2019/05/25 23:50
  • (external edit)