metal/kickstart/files/kickstart.cfg
Dan Voiculeasa b50618ee96 Debian: Add workaround for enabling swacts and unlocks
This work is part of Debian integration effort.
This work only affects Debian.
This work will work around an issue seen during puppet apply on worker
nodes.

This obsoletes workaround [1]. In fact we move the logic here such that
we don't require manual intervention anymore.

Tests on Debian:
PASS: both controllers unlocked on a Standard deployment.
PASS: puppet manifest applied on worker node.
PASS: both controllers unlocked on an AIO-DX deployment.
PASS: swact on AIO-DX by reboot

[1]: https://review.opendev.org/c/starlingx/utilities/+/850541
Related-Bug: https://bugs.launchpad.net/starlingx/+bug/1983580
Signed-off-by: Dan Voiculeasa <dan.voiculeasa@windriver.com>
Change-Id: Idf49b9e19cc733672b7b878b25563ac6ef9d1d67
2022-08-04 19:06:22 +03:00

2342 lines
82 KiB
INI

#
# Copyright (c) 2022 Wind River Systems, Inc.
# SPDX-License-Identifier: Apache-2.0
#
############################################################################
#
# StarlingX Debian Unified System Node Install Kickstart
#
############################################################################
#
# This is the unified kickstart for Debian installation of system nodes.
#
# The Linux Assembly Tool (LAT) performs a unified install for all system
# nodes and exposes boot loader environment variables to this kickstart.
#
# This kickstart must be called with the 'traits=' boot parameter.
# Valid traits are:
#
# controller ... the controller function
# storage ... the storage function
# worker ... the worker function
# lowlatency ... the low latency function
#
# Valid node personality trait groupings ... set configuration function
#
# traits=controller ... Controller
# traits=controller,worker ... All-in-one
# traits=controller,worker,lowlatency ... All-in-one Low Latency
# traits=storage ... Storage
# traits=worker ... Worker
# traits=worker,lowlatency ... Worker Low Latency
#
# Kickstart Stages
#
# Pre Partition - Common Functions Script
# Pre Partition - Volume Remove & Wipe Disk
# Partition - Partition Disks & Create Volumes
# Mkfs - Create Volume Groups & Logical Volumes
# Post - Logical Volume Config
# Post - Traits & Platform Config File update
# Post - Set Kernel Args
# Post - Interface Setup
# Post - Kickstart Finalize Install UUID
# Post - Log Filesystem Setup
# Post Nochroot - Save Install scripts and Logs
# Post Nochroot - Workarounds for enabling integration
# Post Nochroot - Set up /etc/fstab
#
############################################################################
#
# LAT disk install override debug tool interface.
#
# lat-disk --install-device=${INSTDEV} \
# --fat-size=${FSZ} \
# --boot-size=${BSZ} \
# --root-size=${RSZ} \
# --var-size=${VSZ} \
# --inst-flux=0
#
# Notes: exported environment variables changed in 'post' sections
# do not change the original value.
#
###########################################################################
#
# The first kickstart script creates '/tmp/lat/functions' common functions
# file that can be loaded from any of the other hook sections.
#
###########################################################################
# Kickstart Early - Common Functions Script
%ks-early --interpreter=/bin/bash
# Define a hook to report error log if install failed
cat << EOF > /tmp/lat/report_error_log.sh
#!/bin/bash
_dev=\$(blkid --label fluxdata -o device)
if [ "\$_dev" != "" ] ; then
mkdir -p /t
mount -o rw,noatime \$_dev /t
echo "Save install-fail.log to partition fluxdata /var (\$_dev)"
sleep 2
cp /install.log /t/install-fail.log
umount /t
fi
EOF
chmod 755 /tmp/lat/report_error_log.sh
cat << EOF >> /tmp/lat/ks_functions.sh
[ "\${HOOK_LABEL}" = "" ] && HOOK_LABEL="unknown"
export LOG_DIR="var/log"
export LAT_DIR="tmp/lat"
export LOGFILE="/\${LAT_DIR}/kickstart.log"
############################################################################
# log utils
############################################################################
function log()
{
local dt="\$(date "+%Y-%m-%d %H:%M:%S.%3N")"
echo "\$dt kickstart \${HOOK_LABEL} info: \${prefix} \$1" >>\${LOGFILE}
}
function ilog()
{
[ -z "\${stdout}" ] && stdout=1
local dt="\$(date "+%Y-%m-%d %H:%M:%S.%3N")"
echo "\$dt kickstart \${HOOK_LABEL} info: \${prefix} \$1" >&\${stdout}
echo "\$dt kickstart \${HOOK_LABEL} info: \${prefix} \$1" >>\${LOGFILE}
}
function dlog()
{
if [ \${debug} -ne 0 ] ; then
[ -z "\$stdout" ] && stdout=1
local dt="\$(date "+%Y-%m-%d %H:%M:%S.%3N")"
echo "\$dt kickstart \${HOOK_LABEL} debug: \${prefix} \$1" >&\${stdout}
echo "\$dt kickstart \${HOOK_LABEL} debug: \${prefix} \$1" >>\${LOGFILE}
fi
}
function wlog()
{
[ -z "\$stdout" ] && stdout=1
local dt="\$(date "+%Y-%m-%d %H:%M:%S.%3N")"
echo "\$dt kickstart \${HOOK_LABEL} warn: \${prefix} \$1" >&\${stdout}
echo "\$dt kickstart \${HOOK_LABEL} warn: \${prefix} \$1" >>\${LOGFILE}
}
function elog()
{
[ -z "\$stdout" ] && stdout=1
local dt="\$(date "+%Y-%m-%d %H:%M:%S.%3N")"
echo "\$dt kickstart \${HOOK_LABEL} error: \${prefix} \$1" >&\${stdout}
echo "\$dt kickstart \${HOOK_LABEL} error: \${prefix} \$1" >>\${LOGFILE}
}
########################################################################
# Name : report_failure_with_msg
# Purpose : Report installation error, offer a console and
# reboot on exit.
# Parameters: \$1 is the failure message string
# Return : Does not return
########################################################################
function report_failure_with_msg()
{
local msg=\${1}
echo -e '\n\nInstallation failed.\n'
wlog "Installation Failed: ERROR: \${msg}"
echo "... dropping to shell ; exit to reboot ..."
sleep 1
bash
reboot -f
}
########################################################################
# Name : get_disk
# Parameters: \$1 - ??????
# Returns : No return but common disk name is echo's to stdio
#########################################################################
function get_disk()
{
echo "\$(cd /dev ; readlink -f \$1)"
}
#########################################################################
# Name : get_by_path
# Parameters: \$1 - device name i.e. /dev/sda
# Returns : echo of device name by-path
# example: /dev/disk/by-path/pci-0000:03:00.0-scsi-0:2:0:0
#########################################################################
function get_by_path()
{
# log "Function: get_by_path '\${1}'"
local disk=\$(cd /dev ; readlink -f \$1)
for p in /dev/disk/by-path/*; do
if [ "\$disk" = "\$(readlink -f \$p)" ]; then
echo "\$p"
return
fi
done
}
#########################################################################
# Name : get_disk_dev
# Purpose : get the disk name
# Returns : echo of the first disk name found ; base on coded priority
#########################################################################
function get_disk_dev()
{
local disk
# Detect HDD
for blk_dev in vda vdb sda sdb dda ddb hda hdb; do
if [ -d /sys/block/\$blk_dev ]; then
disk=\$(ls -l /sys/block/\$blk_dev | grep -v usb | head -n1 | sed 's/^.*\([vsdh]d[a-z]\+\).*\$/\1/');
if [ -n "\$disk" ]; then
echo "\$disk"
return
fi
fi
done
for blk_dev in nvme0n1 nvme1n1; do
if [ -d /sys/block/\$blk_dev ]; then
disk=\$(ls -l /sys/block/\$blk_dev | grep -v usb | head -n1 | sed 's/^.*\(nvme[01]n1\).*\$/\1/');
if [ -n "\$disk" ]; then
echo "\$disk"
return
fi
fi
done
}
#########################################################################
# Name : exec_retry
# Purpose : Retry operations up to a caller specified ...
# Parameters: $1 - retries - up to number of retries before giving up
# $2 - time in seconds between each retry
# $3 - the command string to execute
# Returns : exit code from last command operation
#########################################################################
function exec_retry()
{
local retries=\${1}
local interval=\${2}
local command=\${3}
# local variables
retry_count=1
local ret_code=0
local ret_stdout=""
command="\${command}" # 2>&\${stdout}"
while [ \${retry_count} -le \${retries} ]; do
# dlog "Running command: '\${command}'."
ret_stdout=\$(eval \${command})
ret_code=\${?}
[ \${ret_code} -eq 0 ] && break
wlog "Error running command '\${command}'. Try \${retry_count} of \${retries} retry in \${interval}s."
wlog "ret_code: \${ret_code}, stdout: '\${ret_stdout}'."
sleep \${interval}
retry_count=\$((retry_count+1))
done
echo "\${ret_stdout}"
return \${ret_code}
}
#########################################################################
# Name : exec_no_fds
# Purpose : Execute command (with retries) after closing fds
# Parameters: $1 - List of volume file descriptors
# $2 - the command string to execute
# $3 - up to number of retries before giving up
# $4 - time in seconds between each retry
# Returns : exit code from last command operation
#########################################################################
function exec_no_fds()
{
# Close open FDs when executing commands that complain about leaked FDs.
local fds=\${1}
local cmd=\${2}
local retries=\${3}
local interval=\${4}
local ret_code=0
local ret_stdout=""
for fd in \${fds}
do
local cmd="\${cmd} \$fd>&-"
done
if [ -z "\${retries}" ]; then
#wlog "Running command: '\${cmd}'."
eval "\${cmd}"
else
ret_stdout=\$(exec_retry "\${retries}" "\${interval}" "\${cmd}")
ret_code=\${?}
echo "\${ret_stdout}"
return \${ret_code}
fi
}
#########################################################################
# Name : is_system_node_install
# Returns : true : 0 if 'pxecontroller' is in $insturl boot arg
# false: 1
#########################################################################
function is_system_node_install()
{
if [[ "\${insturl}" == *"pxecontroller"* ]] ; then
return 0
else
return 1
fi
}
#########################################################################
# Name : is_usb_install
# Returns : true :0
# false:1
#########################################################################
function is_usb_install()
{
pxeurl=\$(echo \${insturl} | sed -e s/ostree_repo//)
if [ "\${pxeurl}" = "file://NOT_SET" ] ; then
return 0
else
return 1
fi
}
#########################################################################
# Name : update_platform_conf
# Purpose : Update the platform.conf file with logging
#########################################################################
PLATFORM_CONF="/etc/platform/platform.conf"
function update_platform_conf()
{
ilog "update \${IMAGE_ROOTFS}\${PLATFORM_CONF} : \${1}"
echo "\${1}" >> \${IMAGE_ROOTFS}\${PLATFORM_CONF}
}
#########################################################################
# Name : get_iface_from_ethname
# Purpose : Translate eth# interface to the alternate predicitive
# interface name'altname'.
# Parameter: eth# name interface string to translate
# Return : echo's of altname interface string
#########################################################################
# TODO: Move to where its used if there is only one section caller
function get_iface_from_ethname()
{
iface=\${1}
# log the interface info for post issue debug
udevadm info --export --query=property --path=/sys/class/net/\${iface} >> \${LOGFILE}
# convert to predictive name: ONBOARD > SLOT > PATH
# https://wiki.debian.org/NetworkInterfaceNames
altname=\$(udevadm info --export --query=property --path=/sys/class/net/\${iface} | grep ID_NET_NAME_ONBOARD)
altname=\${altname#ID_NET_NAME_ONBOARD=}
if [ -z "\${altname}" ] ; then
# try searching for ID_NET_NAME_SLOT
log "... retrying to translate \${iface} to predictive name with ID_NET_NAME_SLOT filter label "
altname=\$(udevadm info --export --query=property --path=/sys/class/net/\${iface} | grep ID_NET_NAME_SLOT)
altname=\${altname#ID_NET_NAME_SLOT=}
fi
if [ -z "\${altname}" ] ; then
# try searching for ID_NET_NAME_PATH
log "... retrying to translate \${iface} to predictive name with ID_NET_NAME_PATH filter label "
altname=\$(udevadm info --export --query=property --path=/sys/class/net/\${iface} | grep ID_NET_NAME_PATH)
altname=\${altname#ID_NET_NAME_PATH=}
fi
# The altname is seen enveloped with tick's ; 'eno1'
# Handle with and without tick's just in case
if [ -z "\${altname}" ] ; then
log "Failed to translate \${iface} to predictive name"
elif [ "\${altname::1}" = "'" ] ; then
echo "\${altname:1:-1}"
else
echo "\${altname}"
fi
}
function display_volume_info ()
{
if [ \${debug} -ne 0 ] ; then
ilog "Volume Info:\${1}"
pvscan 2>/dev/null
pvscan 2>/dev/null >> \${LOGFILE}
lvscan 2>/dev/null
lvscan 2>/dev/null >> \${LOGFILE}
pvdisplay 2>/dev/null
pvdisplay 2>/dev/null >> \${LOGFILE}
lvdisplay 2>/dev/null
lvdisplay 2>/dev/null >> \${LOGFILE}
fi
}
display_mount_info()
{
if [ \${debug} -ne 0 ] ; then
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
lsblk -o name,mountpoint,label,size,uuid
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
fi
}
function log_lvm_conf ()
{
lvm_global_filter=\$(cat /etc/lvm/lvm.conf | grep "global_filter =")
ilog "LVM 'global_filter' Config: \${lvm_global_filter}"
lvm_preferred_names=\$(cat /etc/lvm/lvm.conf | grep "preferred_names =")
ilog "LVM 'lvm_preferred_names' Config: \${lvm_preferred_names}"
}
function breakpoint()
{
echo "*** BREAKPOINT ***: \${1} ; type exit to continue"
bash
echo "continuing from breakpoint: \${1}"
}
function set_variable()
{
touch "/\${LAT_DIR}/\${1}"
}
function get_variable()
{
[ -e "/\${LAT_DIR}/\${1}" ] && return 1
return 0
}
function clr_variable()
{
rm -f "/\${LAT_DIR}/\${1}"
}
#########################################################################
# Name : get_aio_controller_provisioning_sizes
# Purpose : Provide Physical volume / Logical volume sizes
# Parameter: None
# Return : Nothing, but exports key values
#########################################################################
function get_aio_controller_provisioning_sizes()
{
gb=\$((1024*1024*1024))
##
## NOTE: updates to partition sizes need to be also reflected in
## - config/.../sysinv/conductor/manager.py:create_controller_filesystems()
## - config/.../sysinv/common/constants.py
##
## NOTE: When adding partitions, we currently have a max of 4 primary partitions.
## If more than 4 partitions are required, we can use a max of 3 --asprimary,
## to allow 1 primary logical partition with extended partitions
##
## NOTE: Max default PV size must align with the default controllerfs sizes
##
##
## NOTE TO REVIEWERS:
## This section was talen from CentOS and needs to be updated for Debian.
##
##***********************************************************************
## Large disk install (for disks over 240GB)
## - DB size is doubled to allow for upgrades
##
## BACKUP_OVERHEAD = 5GiB
## DEFAULT_PLATFORM_STOR_SIZE = 10GiB
## DEFAULT_DATABASE_STOR_SIZE = 10GiB
## BACKUP = DEFAULT_DATABASE_STOR_SIZE +
## DEFAULT_PLATFORM_STOR_SIZE +
## BACKUP_OVERHEAD = 25GiB
## LOG_VOL_SIZE = 8GiB
## SCRATCH_VOL_SIZE = 16GiB
## RABBIT_LV = 2GiB
## DEFAULT_EXTENSION_STOR_SIZE = 1GiB
## KUBERNETES_DOCKER_STOR_SIZE = 30GiB
## DOCKER_DISTRIBUTION_STOR_SIZE = 16GiB
## ETCD_STOR_SIZE = 5GiB
## CEPH_MON_SIZE = 20GiB
## KUBELET_STOR_SIZE = 10GiB
## DC_VAULT_SIZE = 15GiB
## RESERVED_PE = 16MiB (based on pesize=32768)
##
## MINIMUM_PLATFORM_PV_SIZE = (10 + 2*10 + 25 + 8 + 16 + 2 + 1 + 30 + 16 + 5 + 20 + 10 + 15)GiB + 16MiB/1024 = 178.02GiB
##
##***********************************************************************
## Small disk install - (for disks below 240GB)
## - DB size is doubled to allow for upgrades
##
## DEFAULT_PLATFORM_STOR_SIZE = 10GiB
## DEFAULT_SMALL_DATABASE_STOR_SIZE = 5GiB
## DEFAULT_SMALL_BACKUP_STOR_SIZE = 20GiB
##
## LOG_VOL_SIZE = 8GiB
## SCRATCH_VOL_SIZE = 16GiB
## RABBIT_LV = 2GiB
## DEFAULT_EXTENSION_STOR_SIZE = 1GiB
## KUBERNETES_DOCKER_STOR_SIZE = 30GiB
## DOCKER_DISTRIBUTION_STOR_SIZE = 16GiB
## ETCD_STOR_SIZE = 5GiB
## CEPH_MON_SIZE = 20GiB
## KUBELET_STOR_SIZE = 10GiB
## DC_VAULT_SIZE = 15GiB
## RESERVED_PE = 16MiB (based on pesize=32768)
##
## MINIMUM_PLATFORM_PV_SIZE = (10 + 2*5 + 20 + 8 + 16 + 2 + 1 + 30 + 16 + 5 + 20 + 10 + 15)GiB + 16MiB/1024 = 163.02GiB
##
##***********************************************************************
## Tiny disk install - (for disks below 154GB)
##
## NOTE: Tiny disk setup is mainly for StarlingX running in QEMU/KVM VM.
##
## DEFAULT_TINY_PLATFORM_STOR_SIZE = 1GiB
## DEFAULT_TINY_DATABASE_STOR_SIZE = 1GiB
## DEFAULT_TINY_BACKUP_STOR_SIZE = 1GiB
##
## LOG_VOL_SIZE = 3GiB
## SCRATCH_VOL_SIZE = 2GiB
## RABBIT_LV = 2GiB
## DEFAULT_EXTENSION_STOR_SIZE = 1GiB
## TINY_KUBERNETES_DOCKER_STOR_SIZE = 20GiB
## TINY_DOCKER_DISTRIBUTION_STOR_SIZE = 8GiB
## TINY_ETCD_STOR_SIZE = 1GiB
## TINY_KUBELET_STOR_SIZE = 2GiB
##
## MINIMUM_PLATFORM_PV_SIZE = (1 + 2*1 + 1 + 3 + 2 + 2 + 1 + 20 + 8 + 1 + 2)GiB = 43GiB
##
## MINIMUM_TINY_DISK_SIZE = MINIMUM_PLATFORM_PV_SIZE + ROOTFS_SIZE + EFI_SIZE + BOOT_SIZE + FLUXDATA + PLATFORM_BACKUP_SIZE
## = 43 + 20 + 0.03 + 0.5 + 20 + 1 = 85GiB
# TODO: create a log representing 'free space" on self expand partition.
# TODO: Do the math for this new environment
# The default disk size thresholds must align with the ones in
# config/.../sysinv/common/constants.py
# which are DEFAULT_SMALL_DISK_SIZE
# MINIMUM_SMALL_DISK_SIZE
default_small_disk_size=240
minimum_small_disk_size=196
sz=\$(blockdev --getsize64 \${INSTDEV})
ilog "install disk size:\$sz gb:\$gb"
# Round MINIMUM_PLATFORM_PV_SIZE to the closest upper value that can be divided by 1024.
if [ \${sz} -gt \$((\${default_small_disk_size}*\${gb})) ] ; then
ilog "Large disk: MINIMUM_PLATFORM_PV_SIZE=179GiB*1024=183296"
export MINIMUM_PLATFORM_PV_SIZE=183296
elif [ \${sz} -ge \$((\${minimum_small_disk_size}*\${gb})) ] ; then
ilog "Small disk: MINIMUM_PLATFORM_PV_SIZE=164GiB*1024=167936"
export MINIMUM_PLATFORM_PV_SIZE=167936
else
ilog "Tiny disk: MINIMUM_PLATFORM_PV_SIZE=43GiB*1024=44032"
# Using a disk with a size under 85GiB will fail.
export MINIMUM_PLATFORM_PV_SIZE=44032
export LOG_VOL_SIZE=3000
export SCRATCH_VOL_SIZE=2000
export PLATFORM_BACKUP_SIZE=1000
fi
}
#########################################################################
# Name : get_std_controller_provisioning_sizes
# Purpose : Provide Logical Volume sizes
# Parameter: None
# Return : Nothing, but exports key values
#########################################################################
function get_std_controller_provisioning_sizes()
{
export LOG_VOL_SIZE=8000
export SCRATCH_VOL_SIZE=16000
}
function get_worker_provisioning_sizes()
{
gb=\$((1024*1024*1024))
export LOG_VOL_SIZE=4000
export SCRATCH_VOL_SIZE=4000
## LOG_VOL_SIZE = 4096
## SCRATCH_VOL_SIZE = 4096
## DOCKER = 30720
## CEPH_MON = 20480
## KUBELET_VOL_SIZE = 10240
## RESERVED_PE = 16 (based on pesize=32768)
##
## CGTS_PV_SIZE = 4096 + 4096 + 30720 + 20480 + 10240 + 16 = 69648
##
## Round CGTS_PV_SIZE to the closest upper value that can be divided by 1024.
## 69648/1024=68.01. CGTS_PV_SIZE=69*1024=70656.
export CGTS_PV_SIZE=70656
sz=\$(blockdev --getsize64 \${INSTDEV})
ilog "install disk size:\${sz} gb:\${gb}"
}
##########################################################################
# Global Kickstart Constants #
##########################################################################
#
# NOTE: exported Variables from other segments are NOT visible from functions
#
if [ "\${controller}" = true ] ; then
if [ "\${INSTFLUX}" = 0 ] ; then
BACKUP_PART_NO=5 # in base_bullseye.yaml, instflux=0
else
BACKUP_PART_NO=6 # in base_bullseye.yaml, instflux=1 or not set
fi
case \${INSTDEV} in
*"nvme"*)
BACKUP_PART=\${INSTDEV}p\${BACKUP_PART_NO}
;;
*)
BACKUP_PART=\${INSTDEV}\${BACKUP_PART_NO}
;;
esac
BACKUP_PART_LABEL="platform_backup"
DEFAULT_PERSISTENT_SIZE=30000
# Note that the BA5EBA11-0000-1111-2222- is the prefix used by STX and it's
# defined in sysinv constants.py. Since the 000000000001 suffix is used by
# custom stx LVM partitions, the next suffix is used for the persistent backup
# partition (000000000002)
BACKUP_PART_GUID="BA5EBA11-0000-1111-2222-000000000002"
fi
# Node Personality Trait
TRAIT__CONTROLLER="controller"
TRAIT__STORAGE="storage"
TRAIT__WORKER="worker"
TRAIT__LOWLATENCY="lowlatency"
# System Types
SYSTEM_TYPE__AIO="All-in-one"
SYSTEM_TYPE__STANDARD="Standard"
# Node Subfunctions
SUBFUNCTION__CONTROLLER="\${TRAIT__CONTROLLER}"
SUBFUNCTION__STORAGE="\${TRAIT__STORAGE}"
SUBFUNCTION__WORKER="\${TRAIT__WORKER}"
SUBFUNCTION__AIO="\${TRAIT__CONTROLLER},\${TRAIT__WORKER}"
VOLUME_GROUPS="cgts-vg"
ROOTFS_SIZE=\${RSZ} # 20000
BOOT_SIZE=\${BSZ} # 500
EFI_SIZE=300
LOG_VOL_SIZE=8000
SCRATCH_VOL_SIZE=16000
EOF
###############################
# END of Common Functions Block
###############################
chmod 755 /tmp/lat/ks_functions.sh
HOOK_LABEL="ks-early"
. /tmp/lat/ks_functions.sh
##########################################################################
# Global Kickstart variables #
##########################################################################
export debug=0
export prefix=""
export PLATFORM_BACKUP_SIZE=${DEFAULT_PERSISTENT_SIZE}
# Assume there is no Platform Backup (persistent) Partition
export BACKUP_CREATED=0
export BACKUP_PERSISTED=0
# Platform Backup Partition Info
export BACKUP_PART_FIRST=0
export BACKUP_PART_END=0
export BACKUP_PART_SIZE=0
export BACKUP_PART_FLAGS=0
export BACKUP_PART_NAME=""
export STOR_DEV_FDS="$(ls -1 /proc/$$/fd | egrep -v "^(0|1|2|255)$" | xargs)"
##########################################################################
ilog "***********************************************"
ilog "** Pre Partition - Volume Remove & Wipe Disk **"
ilog "***********************************************"
if [ -z "${traits}" ] ; then
report_failure_with_msg "No install traits specified ; need boot arg traits=<controller|worker|storage|lowlatency>"
fi
ilog "Waiting for disks to be available"
udevadm settle --timeout=300 || report_failure_with_msg "udevadm settle failed"
ilog "Disks became available"
export controller=false
export storage=false
export worker=false
export lowlatency=false
export aio=false
for trait in ${traits//,/ }; do
# dlog "trait:${trait}"
case ${trait} in
"controller") controller=true ;;
"storage") storage=true ;;
"worker") worker=true ;;
"lowlatency") lowlatency=true ;;
*) wlog "unknown trait '${trait}'" ;;
esac
done
# Force enable 'lowlatency' trait if the realtime kernel is detected ; PREEMPT_RT
uname=$(uname -a)
if [[ "${uname}" == *"PREEMPT_RT"* ]] ; then
if [ "${lowlatency}" = false ] ; then
wlog "forcing lowlatency trait after discovering the RT kernel"
lowlatency=true
fi
fi
# Handle trait conbination errors
#
# Handle no valid nodetypes specified
if [ "${controller}" = false -a "${storage}" = false -a "${worker}" = false ] ; then
report_failure_with_msg "No valid install traits specified ; ${traits} ; need boot arg traits=<controller|worker|storage>"
# Storage and controller don't go together
elif [ "${storage}" = true -a "${controller}" = true ] ; then
report_failure_with_msg "Cannot combine storage and controller traits"
# Storage and lowlatency don't go together
elif [ "${storage}" = true -a "${lowlatency}" = true ] ; then
report_failure_with_msg "Cannot combine storage and lowlatency traits"
# Storage and worker don't go together
elif [ "${storage}" = true -a "${worker}" = true ] ; then
report_failure_with_msg "Cannot combine storage and worker traits"
else
ilog "Install traits: $traits"
fi
# setup the install type for the log prefix
if [ "${controller}" = true -a "${worker}" = true ] ; then
aio=true
prefix="${SYSTEM_TYPE__AIO}"
elif [ "${controller}" = true ] ; then
prefix="${TRAIT__CONTROLLER}"
elif [ "${worker}" = true ] ; then
prefix="${TRAIT__WORKER}"
elif [ "${storage}" = true ] ; then
prefix="${TRAIT__STORAGE}"
fi
if [ "${lowlatency}" = true ] ; then
prefix="${prefix}-${TRAIT__LOWLATENCY}"
fi
grep -q 'debug_kickstart' /proc/cmdline
if [ $? -eq 0 ]; then
debug=1
fi
ilog "LAT size parameters: FSZ=${FSZ} BSZ=${BSZ} RSZ=${RSZ} VSZ=${VSZ}"
# First, parse /proc/cmdline to find the boot args
set -- `cat /proc/cmdline`
ilog "/proc/cmdline:$*"
# for I in $*; do case "$I" in *=*) eval $I 2>/dev/null;; esac; done
for arg in $*; do
case "$arg" in
*=*)
eval $arg 2>/dev/null
log "arg : $arg"
;;
esac
done
# Note: This is equivalent to pre_disk_setup_common.cfg
# Name : check_execs
# Purpose: Confirm all the executables required by the kickstart are present
# Returns: 1 of one or more executable are missing
REQUIRED_EXECS="bc blkid dd lvcreate mkfs.ext4 partprobe pvremove pvs sgdisk vgcreate wipefs"
function check_execs()
{
missing_exec=0
for x in ${REQUIRED_EXECS} ; do
which ${x} > /dev/null 2>&1
if [ ${?} -ne 0 ] ; then
elog "dependency check failed ; required '${x}' exec is missing"
missing_exec=1
fi
done
return ${missing_exec}
}
# Log Traits
[ "${controller}" = true ] && ilog "Controller Function"
[ "${storage}" = true ] && ilog "Storage Function"
[ "${worker}" = true ] && ilog "Worker Function"
[ "${lowlatency}" = true ] && ilog "Low Latency Function"
# Log System Type
if [ ${aio} = true ] ; then
ilog "system"
else
ilog "${SYSTEM_TYPE__STANDARD} system"
fi
# Verify that all the required executables are presenty
check_execs
[ $? -ne 0 ] && report_failure_with_msg "Required executables are missing"
####################################################
# pre_common_head (obsolete with lat)
####################################################
# TODO: The installer does not have 'timezone'
# Does LAT handle this ?
wlog "timezone not set ; 'timezone --nontp --utc UTC'"
true
%end
# Pre Partition - Pre Disk Setup Common Script
%pre-part --interpreter=/bin/bash
HOOK_LABEL="pre-part"
. /tmp/lat/ks_functions.sh
#####################################################
# From pre_net_common.cfg for system node installs
#####################################################
if is_system_node_install -eq 0 ; then
# Setup ntp.conf and sync time
cat <<EOF >/etc/ntp_kickstart.conf
server pxecontroller
EOF
if [ -e /usr/sbin/ntpd ] ; then
/usr/sbin/ntpd -g -q -n -c /etc/ntp_kickstart.conf
rc=$?
if [ ${rc} -eq 0 ]; then
if [ -e /sbin/hwclock ] ; then
/sbin/hwclock --systohc --utc
if [ $? -ne 0 ]; then
wlog "failed hwclock command ; /sbin/hwclock --systohc --utc"
else
ilog "ntpd and hwclock set ok"
fi
else
wlog "lat initrd is missing /sbin/hwclock"
fi
else
wlog "ntpd setup failed rc:$rc ; /usr/sbin/ntpd -g -q -n -c /etc/ntp_kickstart.conf"
fi
else
wlog "lat initrd is missing /usr/sbin/ntpd"
fi
fi
#####################################################
# From pre_disk_setup_common.cfg
#####################################################
if [ -n "$INSTDEV" ] ; then
instdev_by_path=$(get_by_path $INSTDEV)
if [ -z ${instdev_by_path} ] ; then
report_failure_with_msg "invalid install device ${INSTDEV}"
else
ilog "Install device: ${INSTDEV} : ${instdev_by_path}"
fi
fi
# Get all block devices of type disk in the system.
# This includes solid state devices.
# Note: /dev/* are managed by kernel tmpdevfs while links in
# /dev/disk/by-path/ are managed by udev which updates them
# asynchronously so avoid using them while performing partition
# operations.
ilog "Detected storage devices:"
STOR_DEVS=""
for f in /dev/disk/by-path/*; do
dev=$(readlink -f $f)
# dlog "found device ${f}"
exec_retry 2 0.5 "lsblk --nodeps --pairs $dev" | grep -q 'TYPE="disk"'
if [ $? -eq 0 ] ; then
# Filter out ISO disk from storage devices
check_valid_dev $dev || continue
STOR_DEVS="$STOR_DEVS $dev"
ilog "Adding ${f} -> ${dev} to managed device list"
fi
done
# Filter STOR_DEVS variable for any duplicates as on some systems udev
# creates multiple links to the same device. This causes issues due to
# attempting to acquire a flock on the same device multiple times.
STOR_DEVS=$(echo "$STOR_DEVS" | xargs -n 1 | sort -u | xargs)
ilog "Unique storage devices: $STOR_DEVS"
if [ -z "$STOR_DEVS" ] ; then
report_failure_with_msg "No storage devices available."
fi
# Lock all devices so that udev doesn't trigger a kernel partition table
# rescan that removes and recreates all /dev nodes for partitions on those
# devices. Since udev events are asynchronous this could lead to a case
# where /dev/ links for existing partitions are briefly missing.
# Missing /dev links leads to command execution failures.
for dev in $STOR_DEVS; do
exec {fd}>$dev || report_failure_with_msg "Error creating file descriptor for $dev."
flock -n "$fd" || report_failure_with_msg "Can't get a lock on fd $fd of device $dev."
STOR_DEV_FDS="$STOR_DEV_FDS $fd"
ilog "Locked ${dev} fd:${fd}"
done
# Log info about system state at beginning of partitioning operation
for dev in $STOR_DEVS; do
ilog "Initial partition table for $dev is:"
# log "Initial partition table for $dev is:"
parted -s $dev unit mib print
# parted -s $dev unit mib print >> ${LOGFILE}
done
display_volume_info "before"
display_mount_info
# Consider removing since LAT already handles this failure mode
# Ensure specified device is not a USB drive
udevadm info --query=property --name=${INSTDEV} |grep -q '^ID_BUS=usb'
if [ $? -eq 0 ]; then
report_failure_with_msg "Specified installation ($INSTDEV) device is a USB drive."
fi
# Log the disk setup
ilog "Volume Groups : ${VOLUME_GROUPS} ; $STOR_DEV_FDS"
# update lvm.conf to prevent udev delays for locked devices
sed -i "s#obtain_device_list_from_udev = 1#obtain_device_list_from_udev = 0#" /etc/lvm/lvm.conf
# Deactivate existing volume groups to avoid Anaconda issues with pre-existing groups
# TODO: May not need this Anaconda specific behavior work around
vgs=$(exec_no_fds "$STOR_DEV_FDS" "vgs --noheadings -o vg_name 2>/dev/null")
if [ -z ${vgs} ] ; then
ilog "No volume groups found"
else
ilog "Found '${vgs}' volume groups"
for vg in $vgs; do
ilog "... disabling $vg"
exec_no_fds "$STOR_DEV_FDS" "vgchange -an $vg 2>/dev/null" 5 0.5
[ $? -ne 0 ] && report_failure_with_msg "Failed to disable $vg."
done
# Remove the volume groups that have physical volumes on the root disk
for vg in $(exec_no_fds "$STOR_DEV_FDS" "vgs --noheadings -o vg_name"); do
exec_no_fds "$STOR_DEV_FDS" "pvs --select \"vg_name=$vg\" --noheadings -o pv_name" | grep -q "${INSTDEV}"
if [ $? -ne 0 ]; then
wlog "Found $vg with no PV on rootfs, ignoring."
continue
fi
ilog "Removing LVs on $vg."
exec_no_fds "$STOR_DEV_FDS" "lvremove --force $vg" 5 0.5 || wlog "WARNING: Failed to remove lvs on $vg."
pvs=$(exec_no_fds "$STOR_DEV_FDS" "pvs --select \"vg_name=$vg\" --noheadings -o pv_name")
wlog "VG $vg has PVs: $(echo $pvs), removing them."
for pv in $pvs; do
ilog "Removing PV $pv."
exec_no_fds "$STOR_DEV_FDS" "pvremove --force --force --yes $pv" 5 0.5
[ $? -ne 0 ] && report_pre_failure_with_msg "ERROR: Failed to remove PV."
done
# VG should no longer be present
vg_check=$(exec_no_fds "$STOR_DEV_FDS" "vgs --select \"vg_name=$vg\" --noheadings -o vg_name")
if [ -n "$vg_check" ]; then
wlog "WARNING: VG $vg is still present after removing PVs! Removing it by force."
exec_no_fds "$STOR_DEV_FDS" "vgremove --force $vg" 5 0.5
[ $? -ne 0 ] && report_pre_failure_with_msg "ERROR: Failed to remove VG."
fi
done
fi
display_volume_info "after"
display_mount_info
ONLYUSE_HDD=""
part_type_guid_str="Partition GUID code"
part_type_name_str="Partition name"
part_type_size_str="Partition size"
part_type_first_str="First sector"
part_type_end_str="Last sector"
part_type_flags_str="Attribute flags"
if [ "$(curl -sf http://pxecontroller:6385/v1/upgrade/$(hostname)/in_upgrade 2>/dev/null)" = "true" ]; then
# In an upgrade, only wipe the disk with the rootfs and boot partition
wlog "In upgrade, wiping only ${INSTDEV}"
WIPE_HDD=${INSTDEV}
ONLYUSE_HDD="$(basename ${INSTDEV})"
else
# Make a list of all the hard drives that are to be wiped.
# Never put the LAT install disk '${INSTDEV}' in that list.
WIPE_HDD=""
# Partition type OSD has a unique globally identifier
CEPH_OSD_GUID="4FBD7E29-9D25-41B8-AFD0-062C0CEFF05D"
CEPH_JOURNAL_GUID="45B0969E-9B03-4F30-B4C6-B4B80CEFF106"
# Check if we wipe OSDs
if [ "$(curl -sf http://pxecontroller:6385/v1/ihosts/wipe_osds 2>/dev/null)" = "true" ]; then
ilog "Wipe OSD data"
WIPE_CEPH_OSDS="true"
else
ilog "Skip Ceph OSD data wipe."
WIPE_CEPH_OSDS="false"
fi
for dev in $STOR_DEVS
do
# TODO: Allowing the install dev 'in' results in a failure mode where
# every second install fails with the following error string
# and unrecoverable mount failure.
#
# Logs:
#
# Warning: The kernel is still using the old partition table.
# The new table will be used at the next reboot or after you
# run partprobe(8) or kpartx(8)
# and then
#
# Failure:
#
# mount: /sysroot: can't find LABEL=otaroot.
#
# Action: Find correct place to put partprobe
#
# Avoid wiping the install root disk
# [ ${dev} == ${INSTDEV} ] && continue
# Avoid wiping USB drives
udevadm info --query=property --name=$dev |grep -q '^ID_BUS=usb' && continue
# Avoid wiping ceph osds if sysinv tells us so
if [ ${WIPE_CEPH_OSDS} == "false" ]; then
wipe_dev="true"
exec_no_fds "$STOR_DEV_FDS" "pvs" | grep -q "$dev *ceph"
if [ $? -eq 0 ]; then
wlog "skip rook provisoned disk $dev"
continue
fi
part_numbers=( `parted -s $dev print | awk '$1 == "Number" {i=1; next}; i {print $1}'` )
# Scanning the partitions looking for CEPH OSDs and
# skipping any disk found with such partitions
for part_number in "${part_numbers[@]}"; do
sgdisk_part_info=$(sgdisk -i $part_number $dev)
part_type_guid=$(echo "$sgdisk_part_info" | grep "$part_type_guid_str" | awk '{print $4;}')
if [ "$part_type_guid" == $CEPH_OSD_GUID ]; then
wlog "OSD found on $dev, skipping wipe"
wipe_dev="false"
break
fi
exec_no_fds "$STOR_DEV_FDS" "pvs" | grep -q -e "${dev}${part_number} *ceph" -e "${dev}p${part_number} *ceph"
if [ $? -eq 0 ]; then
wlog "Rook OSD found on $dev$part_number, skip wipe"
wipe_dev="false"
break
fi
done
if [ "$wipe_dev" == "false" ]; then
continue
fi
fi
# Add device to the wipe list
devname=$(basename $dev)
if [ -e $dev -a "$ISO_DEV" != "../../$devname" -a "$USB_DEV" != "../../$devname" ]; then
ilog "Adding ${dev} to list of disks to be wiped"
if [ -n "$WIPE_HDD" ]; then
ilog "WIPE_HDD=$WIPE_HDD,$dev"
WIPE_HDD=$WIPE_HDD,$dev
else
ilog "WIPE_HDD=$dev"
WIPE_HDD=$dev
fi
fi
done
ilog "Not in upgrade"
fi
ilog "***************************************************"
ilog "WIPE DISKs: ${WIPE_HDD}"
ilog "***************************************************"
by_dev=${INSTDEV}
# TODO: Avoid this loop if the INSTDEV does not have by-path in its name
for f in /dev/disk/by-path/*; do
if [ "${f}" == "${INSTDEV}" ] ; then
by_dev=$(get_disk "${INSTDEV}")
break
fi
done
for dev in ${WIPE_HDD//,/ }
do
ilog "Wiping $dev"
# Clear previous GPT tables or LVM data on each disk.
#
# Rule: Exclude the persistent 'Platform backup' partition.
# Note: Delete the first few bytes at the start and end of the partition.
# This is required with GPT partitions because they save partition
# info at both the start and the end of the block.
# Get a list of partitions for this disk
part_numbers=( $(parted -s $dev print | awk '$1 == "Number" {i=1; next}; i {print $1}') )
# For each '/dev/${dev}${part_number} apply wipe rules
for part_number in "${part_numbers[@]}"; do
sgdisk_part_info=$(sgdisk -i $part_number $dev)
part_name=$(echo "$sgdisk_part_info" | grep "$part_type_name_str" | awk '{print $3;}')
# special handling for the install device '${INSTDEV}'
if [ "${dev}" == "${by_dev}" ] ; then
# Skip over the bios, efi and boot partitions that got us here.
# LAT handles these partitions
case ${part_name} in
"'bios'")
ilog "skipping ${part_name} on ${dev}${part_number}"
continue
;;
"'otaefi'")
ilog "skipping ${part_name} on ${dev}${part_number}"
continue
;;
"'otaboot'")
ilog "skipping ${part_name} on ${dev}${part_number}"
continue
;;
"'otaboot_b'")
ilog "skipping ${part_name} on ${dev}${part_number}"
continue
;;
"'otaroot'")
ilog "skipping ${part_name} on ${dev}${part_number}"
continue
;;
"'fluxdata'")
ilog "skipping ${part_name} on ${dev}${part_number}"
continue
;;
*)
dlog "wipe candidate ${part_name} on ${dev}${part_number}"
;;
esac
fi
# Deal with ssd's which have different partition labelling convention
part=$dev$part_number
case $part in
*"nvme"*)
part=${dev}p${part_number}
;;
esac
if [ "${controller}" = true ] ; then
ilog "Checking platform-backup partition ... $dev : ${INSTDEV} ${by_dev}"
sgdisk_part_info=$(sgdisk -i $part_number $dev)
part_type_guid=$(echo "$sgdisk_part_info" | grep "$part_type_guid_str" | awk '{print $4;}')
if [ "$dev" == "${by_dev}" -a "$part_type_guid" == $BACKUP_PART_GUID ] ; then
part_type_name=$(echo "$sgdisk_part_info" | grep "$part_type_name_str" | awk '{print $3,$4;}')
BACKUP_PART_NAME=${part_type_name:1:-1}
part_type_first=$(echo "$sgdisk_part_info" | grep "$part_type_first_str" | awk '{print $3;}')
BACKUP_PART_FIRST=${part_type_first}
part_type_end=$(echo "$sgdisk_part_info" | grep "$part_type_end_str" | awk '{print $3;}')
BACKUP_PART_END=${part_type_end}
part_type_size=$(echo "$sgdisk_part_info" | grep "$part_type_size_str" | awk '{print $3;}')
BACKUP_PART_SIZE=${part_type_size}
part_type_flags=$(echo "$sgdisk_part_info" | grep "$part_type_flags_str" | awk '{print $3;}')
BACKUP_PART_FLAGS=${part_type_flags}
ilog "Platform Backup: ${BACKUP_PART_NAME}:${BACKUP_PART_FIRST}:${BACKUP_PART_END}:${BACKUP_PART_SIZE}:${part_type_guid}"
part_fstype=$(exec_retry 5 0.5 "blkid -s TYPE -o value $part")
if [ "${part_fstype}" == "ext4" ]; then
ilog "Skipping wipe of persistent partition $part"
BACKUP_CREATED=1
continue
fi
fi
fi
if [ $WIPE_CEPH_OSDS == "true" -a "$part_type_guid" == $CEPH_JOURNAL_GUID ]; then
# Journal partitions require additional wiping. Based on the ceph-manage-journal.py
# script in the integ repo (at the ceph/ceph/files/ceph-manage-journal.py location)
# wiping 100MB of data at the beginning of the partition should be enough. We also
# wipe 100MB at the end, just to be safe.
ilog "Wiping Ceph ${part_name} on ${part} start and end with dd"
dd if=/dev/zero of=$part bs=1M count=100 2>/dev/null
dd if=/dev/zero of=$part bs=1M count=100 seek=$(( `blockdev --getsz $part` / (1024 * 2) - 100 )) 2>/dev/null
else
ilog "STUBBED Wiping ${part_name} on ${part} start and end with dd"
# dd if=/dev/zero of=$part bs=512 count=34 2>/dev/null
# dd if=/dev/zero of=$part bs=512 count=34 seek=$((`blockdev --getsz $part` - 34)) 2>/dev/null
fi
done
if [ ${BACKUP_CREATED} -eq 0 -o "${dev}" != "${by_dev}" ]; then
ilog "Creating disk label for $dev"
parted -s $dev mktable gpt
ilog "... done"
fi
done
# Zap all disks except for the install disk
for dev in $STOR_DEVS; do
if [ ${dev} != "${by_dev}" ] ; then
ilog "Zapping ${dev}"
sgdisk -Zo ${dev}
fi
done
ilog "Destroy otaroot partitions on root disk"
for oldrootlabel in otaroot otaroot_1 otaroot_b otaroot_b_1
do
oldrootpart=$(blkid --label $oldrootlabel)
[ -z "$oldrootpart" ] && continue
oldinstdev=/dev/$(lsblk $oldrootpart -n -o pkname)
ilog "... destroying ${oldrootpart} on ${oldinstdev}"
# sgdisk - Command-line GUID partition table (GPT) manipulator
# Zap the entire partition
ilog "... zapping ${oldinstdev}"
sgdisk -Zo ${oldinstdev}
# partprobe - inform the OS of partition table changes
# root@(none):/# partprobe /dev/sda -s
# /dev/sda: gpt partitions 1 2 3 4 5 6
ilog "... probing ${oldinstdev}"
partprobe ${oldinstdev}
# wipefs - wipe a signature from a device
ilog "... wiping ${oldinstdev}"
wipefs --all --backup ${oldinstdev}
done
# Override installer variable to not prompt for erasing the disk
export INSTW=0
true
%end
###########################################################################
%part --interpreter=/bin/bash
HOOK_LABEL=" part"
. /tmp/lat/ks_functions.sh
ilog "****************************************************"
ilog "*** Partition - Partition Disks & Create Volumes ***"
ilog "****************************************************"
ilog "Allocate host partitions (MB) first:$first"
## NOTE: updates to partition sizes need to be also reflected in
## _controller_filesystem_limits() in sysinv/api/controllers/v1/istorconfig.py
ROOTFS_PART_PREFIX=${INSTDEV}
#check if disk is nvme
case $INSTDEV in
*"nvme"*)
ROOTFS_PART_PREFIX=${INSTDEV}p
;;
esac
###########################################################
# From pre_disk_controller.cfg
###########################################################
# Log the server firmware type
if [ -d /sys/firmware/efi ] ; then
ilog "UEFI Firmware"
else
ilog "BIOS Firmware"
fi
# Only controllers have a persistent partition
# Allocate platform backup partition
if [ "${controller}" = true ] ; then
PLATFORM_BACKUP_SIZE=${DEFAULT_PERSISTENT_SIZE}
if [ -z "$persistent_size" ]; then
# Default backup partition size in MiB
ilog "Platform Backup persistent size not on command line ; defaulting to ${DEFAULT_PERSISTENT_SIZE}"
persistent_size=${DEFAULT_PERSISTENT_SIZE}
fi
if [ ${persistent_size} -lt ${DEFAULT_PERSISTENT_SIZE} ] ; then
wlog "Cannot set persistent_size smaller than default size of ${DEFAULT_PERSISTENT_SIZE} KB"
else
PLATFORM_BACKUP_SIZE=${persistent_size}
fi
ilog "Platform Backup partition size: ${PLATFORM_BACKUP_SIZE}"
if [ ${BACKUP_CREATED} -eq 0 ] ; then
ilog "Platform Backup partition not detected: CREATING"
else
BACKUP_PERSISTED=1
ilog "Platform Backup Partition was detected: PERSISTING"
fi
if [ ${aio} = true ] ; then
ilog "AIO Controller: platform_pv partition - minimizing space allocation"
get_aio_controller_provisioning_sizes
fi
grub_pt_update
end=$(($first+($PLATFORM_BACKUP_SIZE*1024*1024/$lsz)-1))
a="$a -n $p:$first:$end -c $p:${BACKUP_PART_LABEL} -t $p:${BACKUP_PART_GUID}"
elif [ ${worker} = true ] ; then
ilog "Setting up platform_pv partition sizes for worker node"
get_worker_provisioning_sizes
fi
# Allocate platform pv
grub_pt_update
if [ ${aio} = true ] ; then
end=$(($first+(${MINIMUM_PLATFORM_PV_SIZE}*1024*1024/$lsz)-1))
else
ilog "platform_pv partition - using all remaining disk space"
end=$last
fi
a="$a -n $p:$first:$end -c $p:platform_pv -t $p:8E00"
STOR_DEVS=$(echo "$STOR_DEVS" | xargs -n 1 | sort -u | xargs)
[ -z "$STOR_DEVS" ] && report_failure_with_msg "No storage devices available."
ilog "STOR_DEV_FDS Updated ; $STOR_DEV_FDS"
# reset $dev to INSTDEV as LAT installer will partition the disk corresponding
# to that variable
dev=$INSTDEV
dlog "Requesting ${dev} Partition Table: ${a}"
true
%end
###########################################################################
%mkfs --interpreter=/bin/bash
HOOK_LABEL="mkfs"
. /tmp/lat/ks_functions.sh
ilog "****************************************************"
ilog "** Mkfs - Create Volume Groups & Logical Volumes **"
ilog "****************************************************"
#######################################################
# From pre_disk_aio
######################################################
ilog "LAT size parameters: FSZ=${FSZ} BSZ=${BSZ} RSZ=${RSZ} VSZ=${VSZ} gb:${gb}"
vg="volume group"
lv="logical volume"
dev=$(get_disk "${INSTDEV}")
if [ "${controller}" = true ] ; then
LOG_VOL_SIZE=8000
SCRATCH_VOL_SIZE=16000
if [ ! -z "$persistent_size" ]; then
# Default backup partition size in MiB
persistent_size=${DEFAULT_PERSISTENT_SIZE}
fi
# PLATFORM_BACKUP_SIZE=${persistent_size}
ilog "Persistent Size: $persistent_size ${PLATFORM_BACKUP_SIZE}"
fi
if [ "${aio}" = true ] ; then
get_aio_controller_provisioning_sizes
elif [ "${controller}" = true ] ; then
get_std_controller_provisioning_sizes
elif [ "${worker}" = true ] ; then
get_worker_provisioning_sizes
fi
ilog "MINIMUM_PLATFORM_PV_SIZE : ${MINIMUM_PLATFORM_PV_SIZE}"
ilog "SCRATCH_VOL_SIZE : ${SCRATCH_VOL_SIZE}"
ilog "ROOTFS_SIZE : ${ROOTFS_SIZE}"
ilog "LOG_VOL_SIZE : ${LOG_VOL_SIZE}"
if [ "${controller}" = true ] ; then
ilog "PLATFORM_BACKUP_SIZE : ${PLATFORM_BACKUP_SIZE}"
ilog "BACKUP_PART : ${BACKUP_PART}"
ilog "BACKUP_PART_NO : ${BACKUP_PART_NO}"
ilog "BACKUP_PART_LABEL : ${BACKUP_PART_LABEL}"
ilog "BACKUP_PART_GUID : ${BACKUP_PART_GUID}"
# Only init Platform Backup partition filesystem if the partition was just created
pi=$((pi+1))
if [ ${BACKUP_PERSISTED} -eq 0 ] ; then
ilog "Platform Backup Partition was CREATED. Initialize filesystem on ${BACKUP_PART}"
mkfs.ext4 -F -L ${BACKUP_PART_LABEL} ${BACKUP_PART}
[ ${?} -ne 0 ] && report_failure_with_msg "Failed Platform Backup partition filesystem init ${BACKUP_PART}"
fi
fi
# Log important LVM config settings
log_lvm_conf
# Create Volume Group
pi=$((pi+1))
case ${dev} in
*"nvme"*)
pv_part=${dev}p${pi}
;;
*)
pv_part=${dev}${pi}
;;
esac
ilog "cgts--vg-log--lv size: ${LOG_VOL_SIZE} MB"
ilog "cgts--vg-scratch--lv : ${SCRATCH_VOL_SIZE} MB"
ilog "Install disk: ${INSTDEV}"
ilog "Current disk: ${dev} ; current partition index:$pi"
ilog "Physical Volume: ${pv_part}"
ilog "Create ${vg} 'cgts-vg' ${pv_part} ; $STOR_DEV_FDS"
exec_no_fds "$STOR_DEV_FDS" "vgcreate -y --force cgts-vg ${pv_part} 2>/dev/null" 5 0.5
[ ${?} -ne 0 ] && report_failure_with_msg "Failed to create ${vg} 'cgts-vg' ${pv_part}"
# Create and Init the '/var/log' logical volume
ilog "Create ${lv} 'log-lv' ; $STOR_DEV_FDS"
exec_no_fds "$STOR_DEV_FDS" "lvcreate -y -Wy -Zy -n log-lv --size ${LOG_VOL_SIZE}MB cgts-vg 2>/dev/null" 5 0.5
[ ${?} -ne 0 ] && report_failure_with_msg "Failed to create ${lv} 'log-lv'"
ilog "InitFs ${lv} 'log-lv'"
mkfs.ext4 -F /dev/cgts-vg/log-lv
[ ${?} -ne 0 ] && report_failure_with_msg "Failed to init ${lv} 'log-lv'"
# Create and init the '/scratch' logical volume
ilog "Create ${lv} 'scratch-lv' ; $STOR_DEV_FDS"
exec_no_fds "$STOR_DEV_FDS" "lvcreate -y -Wy -Zy -n scratch-lv --size ${SCRATCH_VOL_SIZE}MB cgts-vg 2>/dev/null" 5 0.5
[ ${?} -ne 0 ] && report_failure_with_msg "Failed to create ${lv} 'scratch-lv'"
ilog "InitFs ${lv} 'scratch-lv'"
mkfs.ext4 -F /dev/cgts-vg/scratch-lv
[ ${?} -ne 0 ] && report_failure_with_msg "Failed to init ${lv} 'scratch-lv'"
#######################################################################
# From post_lvm_on_rootfs.cfg (all hosts)
#######################################################################
# uncomment the global_filter line in lvm.conf
perl -0777 -i.bak -pe 's:(# This configuration option has an automatic default value\.\n)\t# global_filter:$1 global_filter:m' /etc/lvm/lvm.conf
perl -0777 -i -pe 's:(# Example\n)\t# preferred_names:$1 preferred_names:m' /etc/lvm/lvm.conf
# Get the LVM disk partition and add it to the lvm.conf file
LV_ROOTDISK=$(exec_no_fds "$STOR_DEV_FDS" "pvdisplay --select 'vg_name=cgts-vg' -C -o pv_name --noheadings")
[ -z ${LV_ROOTDISK} ] && report_failure_with_msg "Failed to identify logical volume rootdisk via pvdisplay"
# Edit the LVM config so LVM only looks for LVs on ${LV_ROOTDISK}
ilog "Edit the LVM config so LVM only looks for LVs on the root disk"
sed -i "s#^\( *\)global_filter = \[.*#\1global_filter = [ \"a|${LV_ROOTDISK}|\", \"r|.*|\" ]#" /etc/lvm/lvm.conf
# Log important LVM config settings
log_lvm_conf
#####################################################################
# From pre_disk_setup_tail.cfg
#####################################################################
# Close all FDs and wait for udev to reshuffle all partitions.
ilog "Releasing storage device locks and FDs."
for fd in $STOR_DEV_FDS
do
flock -u "$fd"
exec {fd}>&-
done
sleep 2
udevadm settle --timeout=300 || report_failure_with_msg "udevadm settle failed"
#lsblk -o name,mountpoint,label,size,uuid
# Rescan LVM cache to avoid warnings for VGs that were recreated.
pvscan --cache 2>/dev/null
true
%end
###########################################################################
%post --interpreter=/bin/bash
HOOK_LABEL="post"
. /tmp/lat/ks_functions.sh
ilog "****************************************************"
ilog "**** Post - Traits & Platform Config File update **"
ilog "****************************************************"
# Set node traits' state
[ "${controller}" = true ] && ilog "Controller Function"
[ "${storage}" = true ] && ilog "Storage Function"
[ "${worker}" = true ] && ilog "Worker Function"
[ "${lowlatency}" = true ] && ilog "Low Latency Function"
[ "${controller}" = true -a ${worker} = true ] && aio=true
# Parse traits to nodetype, subfunction and system_type
# -----------------------------------------------------
# Set nodetype from traits
if [ "${controller}" = true ] ; then
nodetype=${TRAIT__CONTROLLER}
elif [ "${storage}" = true ] ; then
nodetype=${TRAIT__STORAGE}
elif [ "${worker}" = true ] ; then
nodetype=${TRAIT__WORKER}
fi
ilog "nodetype=${nodetype}"
# Set system type and subfunction
subfunction=""
system_type=""
[ "${controller}" = true -a "${worker}" = true ] && aio=true
if [ "${aio}" = true ] ; then
ilog "${SYSTEM_TYPE__AIO} System"
system_type="${SYSTEM_TYPE__AIO}"
subfunction="${SUBFUNCTION__AIO}"
else
ilog "${SYSTEM_TYPE__STANDARD} System"
system_type="${SYSTEM_TYPE__STANDARD}"
if [ "${worker}" = true ] ; then
subfunction=${SUBFUNCTION__WORKER}
elif [ "${storage}" = true ] ; then
subfunction=${SUBFUNCTION__STORAGE}
else
subfunction=${SUBFUNCTION__CONTROLLER}
fi
fi
if [ "${lowlatency}" = true ] ; then
subfunction="${subfunction},${TRAIT__LOWLATENCY}"
fi
ilog "subfunction=${subfunction}"
ilog "system_type=${system_type}"
#################################################################
# From post_platform_conf_controller.cfg
# From post_platform_conf_aio.cfg
# From post_platform_conf_aio_lowlatency.cfg
#################################################################
ilog "create platform.conf and set personality traits"
[ ! -d "/etc/platform" ] && mkdir -p -m 0775 /etc/platform
cat <<EOF > ${PLATFORM_CONF}
nodetype=${nodetype}
subfunction=${subfunction}
system_type=${system_type}
EOF
##############################################################
# From post_pxeboot_controller
# From post_net_common.cfg
# ############################################################
# Set http port
# Persist the default http port number to platform configuration.
# This will get overwritten when by manifest during sw configuration phase.
if [[ "${insturl}" == *"pxecontroller"* && "${insturl}" == *"http"* ]] ; then
http_port=$(echo $(cat /proc/cmdline |xargs -n1 echo |grep '^insturl=' | sed -r 's#^[^/]*://[^/]*:([0-9]*)/.*#\1#'))
else
http_port=8080
fi
update_platform_conf "http_port=${http_port}"
#############################################################
# From post_common.cfg (all hosts)
#############################################################
rm /etc/hostname
# TODO: is this needed with LAT ??
# If using a serial install make sure to add a getty on the tty1
conarg=`cat /proc/cmdline |xargs -n1 echo |grep console= |grep ttyS`
if [ -n "$conarg" ] ; then
echo "1:2345:respawn:/sbin/mingetty tty1" >> /etc/inittab
fi
blkid >> ${LOGFILE}
# TODO: See if other post_common.cfg content is needed
true
%end
###########################################################################
%post --interpreter=/bin/bash
HOOK_LABEL="post"
. /tmp/lat/ks_functions.sh
ilog "****************************************************"
ilog "*** Post - Set Kernel Args ****"
ilog "****************************************************"
###########################################################
# From post_kernel_controller.cfg
# From post_kernel_aio_worker.cfg
###########################################################
. /etc/platform/platform.conf
# Prepare the disk boot kernel comand line
# ----------------------------------------
KERN_OPTS="${KERNEL_PARAMS}"
ilog "Building up KERN_OPTS: ${KERN_OPTS}"
function add_kernel_option()
{
option="${1}"
ilog "... adding: ${option}"
# avoid adding leading space on first option
if [ "${KERN_OPTS}" = "" ] ; then
KERN_OPTS="${option}"
else
KERN_OPTS="${KERN_OPTS} ${option}"
fi
}
# If the installer asked us to use security related kernel params, use
# them in the grub line as well (until they can be configured via puppet)
security_feature=""
# Handle security options
# TODO: Create a list and loop over it
security_options="nopti nospectre_v2 nospectre_v1"
for o in ${security_options}
do
grep -q ${o} /proc/cmdline
if [ $? -eq 0 ]; then
add_kernel_option "${o}"
if [ "${security_feature}" = "" ] ; then
security_feature="${o}"
else
security_feature="${security_feature} ${o}"
fi
fi
done
[ "${KERN_OPTS}" != "" ] && ilog "Learned kernel params: ${KERN_OPTS}"
ilog "Adding kernel options"
if [ "${aio}" = true -o "${worker}" = true ] ; then
if [ -e /etc/init.d/cpumap_functions.sh ] ; then
# Update grub with custom kernel bootargs
source /etc/init.d/cpumap_functions.sh
n_cpus=$(cat /proc/cpuinfo 2>/dev/null | \
awk '/^[pP]rocessor/ { n +=1 } END { print (n>0) ? n : 1}')
ilog "cpumap: n_cpus:${n_cpus}"
n_numa=$(ls -d /sys/devices/system/node/node* 2>/dev/null | wc -l)
ilog "cpumap: n_numa:${n_numa}"
KERN_OPTS="${KERN_OPTS} iommu=pt"
KERN_OPTS="${KERN_OPTS} hugepagesz=2M hugepages=0 default_hugepagesz=2M"
# If this is an all-in-one system, we need at least 4 CPUs
if [ "${aio}" = true -a ${n_cpus} -lt 4 ]; then
report_failure_with_msg "At least 4 CPUs are required for ${SYSTEM_TYPE__AIO} node."
fi
# Add kernel options for cpu isolation / affinity
if [ ${n_cpus} -gt 1 ] ; then
base_cpulist=$(platform_expanded_cpu_list)
ilog "cpumap: base_cpulist: ${base_cpulist}"
base_cpumap=$(cpulist_to_cpumap ${base_cpulist} ${n_cpus})
ilog "cpumap: base_cpumap: ${base_cpumap}"
avp_cpulist=$(vswitch_expanded_cpu_list)
ilog "cpumap: avp_cpulist:${avp_cpulist}"
if [ -e /etc/vswitch/vswitch.conf ] ; then
# Update vswitch.conf
sed -i "s/^VSWITCH_CPU_LIST=.*/VSWITCH_CPU_LIST=\"${avp_cpulist}\"/" /etc/vswitch/vswitch.conf
else
wlog "Missing /etc/vswitch/vswitch.conf ; update bypassed"
fi
norcu_cpumap=$(invert_cpumap ${base_cpumap} ${n_cpus})
ilog "cpumap: norcu_cpumap:${norcu_cpumap}"
norcu_cpulist=$(cpumap_to_cpulist ${norcu_cpumap} ${n_cpus})
ilog "cpumap: norcu_cpulist:${norcu_cpulist}"
if [ "${lowlatency}" = true ]; then
KERN_OPTS="${KERN_OPTS} nohz_full=${norcu_cpulist}"
fi
KERN_OPTS="${KERN_OPTS} rcu_nocbs=${norcu_cpulist}"
KERN_OPTS="${KERN_OPTS} kthread_cpus=${base_cpulist}"
KERN_OPTS="${KERN_OPTS} irqaffinity=${norcu_cpulist}"
fi
else
wlog "Missing /etc/init.d/cpumap_functions.sh ; cpumap setup bypassed"
fi
# Add kernel options to set NMI watchdog
if [ "${lowlatency}" = true ] ; then
add_kernel_option "nmi_watchdog=0 softlockup_panic=0"
else
add_kernel_option "nmi_watchdog=panic,1 softlockup_panic=1"
fi
if [[ "$(dmidecode -s system-product-name)" =~ ^ProLiant.*Gen8$ ]]; then
add_kernel_option "intel_iommu=on,eth_no_rmrr"
else
add_kernel_option "intel_iommu=on"
fi
# Add kernel options to disable kvm-intel.eptad on Broadwell
# Broadwell: Model: 79, Model name: Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
if grep -q -E "^model\s+:\s+79$" /proc/cpuinfo
then
add_kernel_option "kvm-intel.eptad=0"
fi
# Add kernel option to avoid jiffies_lock contention on real-time kernel
if [ "${lowlatency}" = true ] ; then
add_kernel_option "skew_tick=1"
fi
elif [ "${controller}" = true ] ; then
ilog "Adding ${TRAIT__CONTROLLER} function kernel options"
## Custom kernel options
add_kernel_option "intel_iommu=off usbcore.autosuspend=-1"
## Setup the loop module to support up to 15 partitions so that we
## can enable the customer to manually resize images if needed.
##
add_kernel_option "loop.max_part=15"
# Add kernel options to ensure NMI watchdog is enabled, if supported
add_kernel_option "nmi_watchdog=panic,1 softlockup_panic=1"
elif [ "${storage}" = true ] ; then
ilog "Adding ${TRAIT__STORAGE} function kernel options"
## Custom kernel options
add_kernel_option "intel_iommu=off usbcore.autosuspend=-1"
# Add kernel options to ensure NMI watchdog is enabled, if supported
add_kernel_option "nmi_watchdog=panic,1 softlockup_panic=1"
fi
#########################################################################################
# From post_kernel_aio_and_worker.cfg
# From post_kernel_controller.cfg
# From post_kernel_storage.cfg
#########################################################################################
# Add kernel options to ensure an selinux is disabled for all node types
add_kernel_option "selinux=0 enforcing=0"
# Add kernel option to panic on a softdog timeout
add_kernel_option "softdog.soft_panic=1"
# Make sure that we are using cgroups v1
add_kernel_option "systemd.unified_cgroup_hierarchy=0"
# k8s updates
add_kernel_option "user_namespace.enable=1"
# Add kernel option to disable biosdevname if enabled
# As this may already be in GRUB_CMDLINE_LINUX, only add if it is not already present
grep -q '^GRUB_CMDLINE_LINUX=.*biosdevname=0' /etc/default/grub
if [ $? -ne 0 ]; then
add_kernel_option "biosdevname=0"
fi
########################################################################################
ilog "Adding these kernel params to disk boot: ${KERN_OPTS}"
if [ -n "${KERN_OPTS}" ] ; then
grep -q "^kernel_params=" /boot/efi/EFI/BOOT/boot.env
if [ ${?} -ne 0 ]; then
# Add line
sed -i "1 a kernel_params=${KERN_OPTS}" /boot/efi/EFI/BOOT/boot.env
else
# Update existing
sed -i "s/^kernel_params=.*/kernel_params=${KERN_OPTS}/" /boot/efi/EFI/BOOT/boot.env
fi
else
wlog "no kernel options added"
fi
######################################################################
# From post_system_aio
######################################################################
if [ "${aio}" = true ] ; then
## Reserve more memory for base processes since the controller has higher
## memory requirements but cap it to better handle systems with large
## amounts of memory
TOTALMEM=$(grep MemTotal /proc/meminfo | awk '{print int($2/1024)}')
ilog "${SYSTEM_TYPE__AIO} MemTotal:${TOTALMEM}"
if [ -e /sys/devices/system/node/node0 ]; then
RESERVEDMEM=$(grep MemTotal /sys/devices/system/node/node0/meminfo | awk '{printf "%d\n", $4/1024}')
else
RESERVEDMEM=$(grep MemTotal /proc/meminfo | awk '{print int($2/1024/4)}')
fi
if [ ${RESERVEDMEM} -lt 6144 ]; then
RESERVEDMEM=6144
elif [ ${RESERVEDMEM} -gt 14500 ]; then
RESERVEDMEM=14500
elif [ ${RESERVEDMEM} -gt 8192 ]; then
RESERVEDMEM=8192
fi
ilog "${SYSTEM_TYPE__AIO} Reserved Memory: ${RESERVEDMEM}"
sed -i -e "s#\(WORKER_BASE_RESERVED\)=.*#\1=(\"node0:${RESERVEDMEM}MB:1\" \"node1:2000MB:0\" \"node2:2000MB:0\" \"node3:2000MB:0\")#g" /etc/platform/worker_reserved.conf
worker_reserved=$(grep WORKER_BASE_RESERVED /etc/platform/worker_reserved.conf)
ilog "${SYSTEM_TYPE__AIO} '${worker_reserved}'"
# Update WORKER_CPU_LIST
N_CPUS=$(cat /proc/cpuinfo 2>/dev/null | awk '/^[pP]rocessor/ { n +=1 } END { print (n>0) ? n : 1}')
sed -i "s/^WORKER_CPU_LIST=.*/WORKER_CPU_LIST=\"0-$((N_CPUS-1))\"/" /etc/platform/worker_reserved.conf
worker_cpu_list=$(grep WORKER_CPU_LIST /etc/platform/worker_reserved.conf)
ilog "${SYSTEM_TYPE__AIO} '${worker_cpu_list}'"
fi
true
%end
###########################################################################
%post --interpreter=/bin/bash --nochroot
HOOK_LABEL="post"
. /tmp/lat/ks_functions.sh
ilog "****************************************************"
ilog "*** Post - Interface Setup ***"
ilog "****************************************************"
###########################################################
# From post_pxeboot_controller
# From post_net_common.cfg
###########################################################
# TODO: Not needed on a USB install.
# TODO: Need to adjust fault handling or condition on USB install.
# Obtain the boot interface from the PXE boot
BOOTIF=$(cat /proc/cmdline |xargs -n1 echo |grep BOOTIF=)
BOOTIF=${BOOTIF#BOOTIF=}
mgmt_dev=lo
mgmt_vlan=0
if [ -n "$BOOTIF" ] ; then
BOOTIF=$(echo $BOOTIF | sed -r -e 's/.*(..-..-..-..-..-..)$/\1/' -e 's/-/:/g')
ndev=`ip link show |grep -B 1 $BOOTIF |head -1 |awk '{print $2}' |sed -e 's/://'`
if [ -n "$ndev" ] ; then
# convert to predictive name
mgmt_dev=$(get_iface_from_ethname $ndev)
if [ "${mgmt_dev}" == "" ] ; then
report_failure_with_msg "failed to get predictive altname from ${ndev}"
fi
# get vlan info for system node installs
if is_system_node_install -eq 0 ; then
# Retrieve the management VLAN from sysinv if it exists
ilog "Querying system inventory for management vlan id"
mgmt_vlan=`curl -sf http://pxecontroller:6385/v1/isystems/mgmtvlan`
rc=$?
if [ ${rc} -ne 0 ] ; then
report_failure_with_msg "Unable to communicate with System Inventory REST API. Aborting installation. rc:${rc}"
fi
ilog "Management Interface: ${ndev} -> ${mgmt_dev} -> vlan${mgmt_vlan}"
else
ilog "Management Interface: ${ndev} -> ${mgmt_dev}"
fi
else
report_failure_with_msg "Unable to determine mgmt interface from BOOTIF=$BOOTIF."
fi
else
wlog "BOOTIF is not set. Unable to determine mgmt interface."
fi
ilog "mgmt_dev : $mgmt_dev"
ilog "mgmt_vlan: $mgmt_vlan"
if [ ! -e "${IMAGE_ROOTFS}/etc/network/interfaces" ] ; then
cat << EOF >> ${IMAGE_ROOTFS}/etc/network/interfaces
# This file describes the network interfaces available on the system
# and how to activate them. For more information , see interfaces(5)
source ${IMAGE_ROOTFS}/etc/network/interfaces.d/*
EOF
fi
if [ ! -d "${IMAGE_ROOTFS}/etc/network/interfaces.d" ] ; then
mkdir -p -m 0775 ${IMAGE_ROOTFS}/etc/network/interfaces.d
fi
ilog "Setup network scripts"
if [ $mgmt_vlan -eq 0 ] ; then
# Persist the boot device to the platform configuration. This will get
# overwritten later if the management_interface is on a bonded interface.
update_platform_conf "management_interface=$mgmt_dev"
# Build networking scripts
cat << EOF > ${IMAGE_ROOTFS}/etc/network/interfaces.d/ifcfg-lo
auto lo
iface lo inet loopback
EOF
if [ $mgmt_dev != "lo" ]; then
cat << EOF > ${IMAGE_ROOTFS}/etc/network/interfaces.d/ifcfg-$mgmt_dev
auto $mgmt_dev
iface $mgmt_dev inet dhcp
post-up echo 0 > /proc/sys/net/ipv6/conf/lo/autoconf; echo 0 > /proc/sys/net/ipv6/conf/lo/accept_ra; echo 0 > /proc/sys/net/ipv6/conf/lo/accept_redirects
EOF
fi
else
# Check whether to use inet or inet6
ipv6_addr=$(dig +short AAAA controller)
if [[ -n "$ipv6_addr" ]]
then
mgmt_address_family=inet6
ipv6init=yes
dhcpv6c=yes
dhclientargs=-1
else
mgmt_address_family=inet
ipv6init=no
dhcpv6c=no
dhclientargs=
fi
# Persist the boot device to the platform configuration. This will get
# overwritten later if the management_interface is on a bonded interface.
update_platform_conf "management_interface=vlan$mgmt_vlan"
# Build networking scripts
cat << EOF > ${IMAGE_ROOTFS}/etc/network/interfaces.d/ifcfg-lo
auto lo
iface lo $mgmt_address_family static
address 127.0.0.1
netmask 255.0.0.0
post-up echo 0 > /proc/sys/net/ipv6/conf/lo/autoconf; echo 0 > /proc/sys/net/ipv6/conf/lo/accept_ra; echo 0 > /proc/sys/net/ipv6/conf/lo/accept_redirects
EOF
cat << EOF > ${IMAGE_ROOTFS}/etc/network/interfaces.d/ifcfg-$mgmt_dev
auto $mgmt_dev
iface $mgmt_dev $mgmt_address_family manual
post-up echo 0 > /proc/sys/net/ipv6/conf/lo/autoconf; echo 0 > /proc/sys/net/ipv6/conf/lo/accept_ra; echo 0 > /proc/sys/net/ipv6/conf/lo/accept_redirects
EOF
cat << EOF > ${IMAGE_ROOTFS}/etc/network/interfaces.d/ifcfg-vlan$mgmt_vlan
auto vlan$mgmt_vlan
iface vlan$mgmt_vlan $mgmt_address_family dhcp
vlan-raw-device $mgmt_dev
post-up echo 0 > /proc/sys/net/ipv6/conf/lo/autoconf; echo 0 > /proc/sys/net/ipv6/conf/lo/accept_ra; echo 0 > /proc/sys/net/ipv6/conf/lo/accept_redirects
EOF
# Reject DHCPOFFER from DHCP server that doesn't send
# wrs-install-uuid option
echo "require wrs-install-uuid;" >>/etc/dhcp/dhclient.conf
echo "require dhcp6.wrs-install-uuid;" >>/etc/dhcp/dhclient.conf
# Bring up the mgmt vlan so that a dhcp lease is acquired and an address is
# setup prior to the post-install reboot. This is so that the timing of the IP
# address allocation is similar to how normal/non-pxe installation works.
mgmt_iface=vlan$mgmt_vlan
ilog "mgmt_iface=vlan$mgmt_vlan"
ilog "mgmt_address_family: $mgmt_address_family"
dhclient_family=$([[ $mgmt_address_family == "inet" ]] && echo -4 || echo -6)
ilog "dhclient_family: $dhclient_family"
ilog "ip link add link $mgmt_dev name $mgmt_iface type vlan id $mgmt_vlan"
ip link add link $mgmt_dev name $mgmt_iface type vlan id $mgmt_vlan
ilog "ip link set up dev $mgmt_iface"
ilog "dhclient $dhclient_family $mgmt_iface || true"
ip link set up dev $mgmt_iface
dhclient $dhclient_family $mgmt_iface || true
fi
true
%end
##########################################################################
%post --interpreter=/bin/bash --nochroot
HOOK_LABEL="post_nochroot"
. /tmp/lat/ks_functions.sh
ilog "****************************************************"
ilog "*** Post - Kickstart Finalize Install UUID ***"
ilog "****************************************************"
# Create a uuid specific to this installation
# install_uuid under /var needs to match what is written to /etc/platform/platform.conf
# When instflux=0 (/var not on a dedicated fluxdata partition)
# When instflux=1 (/var is part of the two different sysroot deployments).
# Therefore check if the file has been written and use that, otherwise generate it
feed="${IMAGE_ROOTFS}/var/www/pages/feed/rel-xxxPLATFORM_RELEASExxx"
[ ! -d "${feed}" ] && mkdir -p -m 0755 ${feed}
$(is_system_node_install)
if [ $? -ne 0 ] ; then
if [ -e "${LAT_DIR}/INSTALL_UUID" ]; then
INSTALL_UUID=$(< "${LAT_DIR}/INSTALL_UUID")
ilog "Using saved install uuid ${INSTALL_UUID}"
else
INSTALL_UUID=`uuidgen`
ilog "Generated install uuid ${INSTALL_UUID}"
echo "${INSTALL_UUID}" > ${LAT_DIR}/INSTALL_UUID
fi
ilog "... adding to ${feed}"
echo ${INSTALL_UUID} > ${feed}/install_uuid
ilog "... adding to ${PLATFORM_CONF}"
update_platform_conf "INSTALL_UUID=${INSTALL_UUID}"
else
pxeurl=$(echo $insturl | sed -e s/ostree_repo//)
# Check for noverifyssl
if grep -q noverifyssl /proc/cmdline; then
NOVERIFYSSL_WGET_OPT="--no-check-certificate"
else
NOVERIFYSSL_WGET_OPT=""
fi
ilog "Fetching install uuid from ${pxeurl}"
if [ "${controller}" = true ] ; then
ilog "... adding to ${feed}"
pushd ${feed} > /dev/null
else
# must be a worker or storage node install
pushd /tmp > /dev/null
# There is no feed function on non-controller nodes
# TODO: Prevent feed dir packaging on non-controller nodes
rm -rf ${IMAGE_ROOTFS}/var/www/pages/feed
fi
if [ ! -e ./install_uuid ] ; then
wget ${NOVERIFYSSL_WGET_OPT} ${pxeurl}/install_uuid -o /${LAT_DIR}/wget_install_uuid.log
[ $? -ne 0 ] && report_failure_with_msg "Failed to fetch install_uuid from pxeboot server"
fi
if [ -e ./install_uuid ] ; then
INSTALL_UUID=$(cat install_uuid)
else
report_failure_with_msg "Failed to find fetched install_uuid file"
fi
popd > /dev/null
ilog "... adding to ${PLATFORM_CONF}"
update_platform_conf "INSTALL_UUID=${INSTALL_UUID}"
fi
true
%end
##########################################################################
%post --interpreter=/bin/bash
HOOK_LABEL="post"
. /tmp/lat/ks_functions.sh
ilog "****************************************************"
ilog "*** Post - Log Filesystem Setup ***"
ilog "****************************************************"
display_volume_info "final"
true
%end
##########################################################################
%post --interpreter=/bin/bash --nochroot
HOOK_LABEL="post_nochroot"
. /tmp/lat/ks_functions.sh
ilog "****************************************************"
ilog "*** Post Nochroot - Save Install Scripts and Logs **"
ilog "****************************************************"
ilog "IMAGE_ROOTFS=${IMAGE_ROOTFS}"
get_variable "ostree_repo_fetched"
OSTREE_REPO_FETCHED=$?
# Fetch ostree
if [ "${controller}" = true ] ; then
sw_release="xxxPLATFORM_RELEASExxx"
# -1 is all commits, positive number is that number of last commits
commits="--depth=-1"
pull_options="${commits} --mirror"
pxeboot="${IMAGE_ROOTFS}/var/pxeboot"
feed="${IMAGE_ROOTFS}/var/www/pages/feed/rel-${sw_release}"
repo="${feed}/ostree_repo"
mkdir -p "${repo}"
mkdir -p "${feed}"
mkdir -p "${feed}/pxeboot"
mkdir -p "${feed}/kickstart"
mkdir -p "${pxeboot}/rel-${sw_release}"
if [ ${OSTREE_REPO_FETCHED} -eq 0 ] ; then
ilog "Pull ostree_repo to ${repo}"
ostree --repo=${repo} init --mode=archive
if [ "${insturl}" = "file://NOT_SET" ] ; then
ostree --repo=${repo} remote add ${instbr} file:///instboot/ostree_repo
else
ostree --repo=${repo} remote add ${instbr} ${insturl}
fi
ostree --repo=${repo} pull ${pull_options} ${instbr}:${instbr}
# This is used by patching.
# Set ostree remote to the local install feed
file_feed="file:///var/www/pages/feed/rel-${sw_release}/ostree_repo/"
feed_branch="starlingx"
ilog "Replacing ostree sysroot remote with: ${file_feed} ${feed_branch}"
ostree --repo=/sysroot/ostree/repo remote delete ${instname}
ostree --repo=/sysroot/ostree/repo remote add ${instname} ${file_feed} ${feed_branch}
# This fetch is only needed once because the repo is stored in /var
set_variable "ostree_repo_fetched"
fi
# Setup the feed and pxeboot directories
# ######################################
#
# Check for noverifyssl
if grep -q noverifyssl /proc/cmdline; then
NOVERIFYSSL_WGET_OPT="--no-check-certificate"
else
NOVERIFYSSL_WGET_OPT=""
fi
# handle USB install
if is_usb_install -eq 0 ; then
pushd ${feed}/pxeboot > /dev/null
ilog "Copy bzImage, initrd and respective secure boot .sig files"
ilog "... from /instboot/pxeboot to ${feed}/pxeboot and ${pxeboot}/rel-${sw_release}"
cp -a /instboot/pxeboot/bzImage* .
cp -a /instboot/pxeboot/initrd* .
cp -a /instboot/efi.img ${feed}
cp -a bzImage* ${pxeboot}/rel-${sw_release}
cp -a initrd* ${pxeboot}/rel-${sw_release}
ilog "Copy pxeboot utilities from /instboot/pxeboot to ${pxeboot}"
for f in pxelinux.0 libcom32.c32 ldlinux.c32 libutil.c32 vesamenu.c32 grubx64.efi; do
cp -a /instboot/pxeboot/${f} .
cp -a /instboot/pxeboot/${f} ${pxeboot}
done
cp -a /instboot/efi.img ${pxeboot}
cp -a /instboot/pxeboot/EFI ${pxeboot}
cp -a /instboot/pxeboot/EFI ${feed}/pxeboot
cp -a /instboot/kickstart/kickstart.cfg ${feed}/kickstart
popd > /dev/null
# handle pxeboot install
else
pxeurl=$(echo $insturl | sed -e s/ostree_repo//)
ilog "Fetch bzImage and initrd files from ${pxeurl}/pxeboot to ${feed}/pxeboot and ${pxeboot}/rel-${sw_release}"
pushd ${feed}/pxeboot > /dev/null
for f in bzImage bzImage-rt bzImage-rt.sig bzImage.sig bzImage-std bzImage-std.sig initrd initrd.sig; do
if [ ! -e "./${f}" ] ; then
ilog "... fetching ${f} to ${feed}/pxeboot"
wget ${NOVERIFYSSL_WGET_OPT} ${pxeurl}/pxeboot/${f} -o /${LAT_DIR}/wget.tmp
[ $? -ne 0 ] && report_failure_with_msg "Failed to find ${pxeurl}/pxeboot/${f}"
cat /${LAT_DIR}/wget.tmp >> /${LAT_DIR}/wget_pxeboot_setup.log
fi
# also copy it to the /var/pxeboot release dir
if [ -e "./${f}" -a ! -e "${pxeboot}/rel-${sw_release}/${f}" ] ; then
cp ${f} ${pxeboot}/rel-${sw_release}
ilog "... copying ${f} to ${pxeboot}/rel-${sw_release}"
fi
done
popd > /dev/null
ilog "Fetch pxeboot utilities from ${pxeurl}/pxeboot to ${pxeboot}"
pushd ${feed}/pxeboot > /dev/null
for f in pxelinux.0 libcom32.c32 ldlinux.c32 libutil.c32 vesamenu.c32 grubx64.efi; do
if [ ! -e "./${f}" ] ; then
ilog "... fetching ${f} to ${feed}/pxeboot"
wget ${NOVERIFYSSL_WGET_OPT} ${pxeurl}/pxeboot/${f} -o /${LAT_DIR}/wget.tmp
[ $? -ne 0 ] && report_failure_with_msg "Failed to get ${pxeurl}/pxeboot/${f}"
cat /${LAT_DIR}/wget.tmp >> /${LAT_DIR}/wget_pxeboot_setup.log
fi
# also copy it to the /var/pxeboot directory
if [ -e "./${f}" -a ! -e "${pxeboot}/${f}" ] ; then
ilog "... copying ${f} to ${pxeboot}"
cp ${f} ${pxeboot}
fi
done
popd > /dev/null
ilog "Fetch efi.img from ${pxeurl} to ${feed}"
pushd ${feed} > /dev/null
for f in efi.img ; do
if [ ! -e "./${f}" ] ; then
ilog "... fetching ${f} to ${feed}"
wget ${NOVERIFYSSL_WGET_OPT} ${pxeurl}/${f} -o /${LAT_DIR}/wget.tmp
[ $? -ne 0 ] && report_failure_with_msg "Failed to get ${pxeurl}/${f}"
cat /${LAT_DIR}/wget.tmp >> /${LAT_DIR}/wget_pxeboot_setup.log
fi
# also copy it to the /var/pxeboot directory
if [ -e "./${f}" -a ! -e "${pxeboot}/${f}" ] ; then
ilog "... copying ${f} to ${pxeboot}"
cp ${f} ${pxeboot}
fi
done
popd > /dev/null
ilog "Fetch files from ${pxeurl}/pxeboot/EFI/BOOT to ${feed}/pxeboot/EFI/BOOT"
mkdir -p ${pxeboot}/EFI/BOOT
mkdir -p ${feed}/pxeboot/EFI/BOOT
pushd ${pxeboot}/EFI/BOOT > /dev/null
for f in bootx64.efi bootx64-nosig.efi grub.cfg.sig grubx64.efi LockDown.efi LockDown.efi.sig mmx64.efi; do
if [ ! -e "./${f}" ] ; then
ilog "... fetching ${f} to ${pxeboot}/EFI/BOOT"
wget ${NOVERIFYSSL_WGET_OPT} ${pxeurl}/pxeboot/EFI/BOOT/${f} -o /${LAT_DIR}/wget.tmp
[ $? -ne 0 ] && report_failure_with_msg "Failed to get ${pxeurl}/pxeboot/EFI/BOOT/${f}"
cat /${LAT_DIR}/wget.tmp >> /${LAT_DIR}/wget_pxeboot_setup.log
fi
if [ -e "./${f}" -a ! -e ${feed}/pxeboot/EFI/BOOT/${f} ] ; then
ilog "... copying ${f} to ${feed}/pxeboot/EFI/BOOT"
cp ${f} ${feed}/pxeboot/EFI/BOOT
fi
done
popd > /dev/null
ilog "Fetch kickstarts from ${pxeurl} to ${feed}/kickstart"
pushd ${feed}/kickstart > /dev/null
for f in kickstart.cfg ; do
if [ ! -e ${f} ] ; then
ilog "... fetching ${f} to ${feed}/kickstart"
wget ${NOVERIFYSSL_WGET_OPT} ${pxeurl}/kickstart/${f} -o /${LAT_DIR}/wget.tmp
[ $? -ne 0 ] && report_failure_with_msg "Failed to get ${pxeurl}/kickstart/${f}"
cat /${LAT_DIR}/wget.tmp >> /${LAT_DIR}/wget_pxeboot_setup.log
fi
done
[ -e /${LAT_DIR}/wget.tmp ] && rm -f /${LAT_DIR}/wget.tmp
popd > /dev/null
fi
# Temporary WorkAround: The current UEFI pxeboot loader does not call the
# default provisioning grub menu in /var/pxeboot/pxelinux.cfg/grub.cfg.
#
# While the above issue is investigated, to support DX and system node
# install for UEFI servers this code moves the lat grub.cfg aside and
# creates a link to the default provisioning mac based grub menu.
pushd ${pxeboot}/EFI/BOOT > /dev/null
if [ ! -L grub.cfg ] ; then
if [ -e grub.cfg ] ; then
mv grub.cfg grub.cfg.lat
fi
ln -s ../../pxelinux.cfg/grub.cfg
fi
popd > /dev/null
fi
# Save the install scripts and kickstart logs
mount /dev/mapper/cgts--vg-log--lv "${IMAGE_ROOTFS}/${LOG_DIR}"
if [ ${?} -ne 0 ] ; then
elog "Failed to mount /dev/mapper/cgts--vg-log--lv"
else
if [ -e "${IMAGE_ROOTFS}/${LOG_DIR}" ]; then
cp -a /${LAT_DIR} ${IMAGE_ROOTFS}/${LOG_DIR}
cp /install ${IMAGE_ROOTFS}/${LOG_DIR}/lat
ilog "Saved installer data to ${IMAGE_ROOTFS}/${LOG_DIR}"
else
wlog "Could not save installer data"
fi
umount "${IMAGE_ROOTFS}/${LOG_DIR}"
fi
true
%end
##########################################################################
%post --interpreter=/bin/bash --nochroot
HOOK_LABEL="post_nochroot"
. /tmp/lat/ks_functions.sh
# This section needs to be removed when solutions are implemented
ilog "***********************************************************************"
ilog "*** Post Nochroot - Workarounds for enabling integration ***"
ilog "***********************************************************************"
# Workaround for enabling swacts on AIO-DX
# Workaround for enabling compute unlocks
# Launchpad: #1983580
rm ${IMAGE_ROOTFS}/var/lib/dpkg/triggers/Unincorp
true
%end
##########################################################################
%post --interpreter=/bin/bash --nochroot
HOOK_LABEL="post_nochroot"
. /tmp/lat/ks_functions.sh
# This needs to update all available ostree based rootfs
ilog "****************************************************"
ilog "*** Post Nochroot - Set up /etc/fstab ***"
ilog "****************************************************"
if [ ${controller} = true ] ; then
mkdir -p ${IMAGE_ROOTFS}/var/rootdirs/opt/platform-backup
echo -e "LABEL=platform_backup\t/var/rootdirs/opt/platform-backup\text4\tdefaults\t1 2" >> ${IMAGE_ROOTFS}/etc/fstab
elif [ ${worker} = true ] ; then
mkdir -p ${IMAGE_ROOTFS}/var/rootdir/opt/platform
echo -e "controller-platform-nfs:/opt/platform\t/opt/platform\tnfs\ttimeo=30,udp,rsize=1024,wsize=1024,_netdev 0 0" >> ${IMAGE_ROOTFS}/etc/fstab
fi
mkdir -p ${IMAGE_ROOTFS}/var/rootdirs/scratch
echo -e "/dev/mapper/cgts--vg-scratch--lv\t/var/rootdirs/scratch\text4\tdefaults\t1 2" >> ${IMAGE_ROOTFS}/etc/fstab
mkdir -p ${IMAGE_ROOTFS}/var/log
echo -e "/dev/mapper/cgts--vg-log--lv\t/var/log\text4\tdefaults\t1 2" >> ${IMAGE_ROOTFS}/etc/fstab
# Create first_boot flag
touch ${IMAGE_ROOTFS}/etc/platform/.first_boot
true
%end