====== OS Install: Post Install ======
**General Information**
After installing an OS via [[linux_wiki:os_install_kickstart|kickstart]] or a [[linux_wiki:os_install_vm_template|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
----
===== Firstboot: The script =====
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: CentOS 7 Service =====
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
----
===== Firstboot: CentOS 6 Service =====
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.
----
===== Auto Setup: VM Templates =====
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 ([[linux_wiki:os_install_vm_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 :/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
* [[linux_wiki:os_install_vm_template#centos_6vm_cleanup|Run CentOS 6 clean up commands]] identical to the base template and create a new template.
* **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 :/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
* [[linux_wiki:os_install_vm_template#centos_7vm_cleanup|Run CentOS 7 clean up commands]] identical to the base template and create a new template.
----
===== Auto Setup: Kickstarts =====
Kickstart files require a post install section to be edited in order for the firstboot script to be placed on a new system.
* [[linux_wiki:os_install_kickstart|Create a kickstart file]] as normal
* 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
#!/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
#!/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= --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= --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
----