3231 lines
126 KiB
Bash
3231 lines
126 KiB
Bash
#
|
|
# Copyright (c) 2022-2024 Wind River Systems, Inc.
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
############################################################################
|
|
#
|
|
# StarlingX Debian Unified Miniboot/USB Install Kickstart
|
|
#
|
|
############################################################################
|
|
#
|
|
# This is the unified kickstart for Debian installation of subcloud nodes
|
|
# from the USB or over Redfish.
|
|
#
|
|
# IMPORTANT:
|
|
# This file is derived from kickstart.cfg. Since we must pull bug fixes
|
|
# from kickstart.cfg, developers should be mindful to minimize the diff
|
|
# between the two files.
|
|
#
|
|
# The Linux Assembly Tool (LAT) performs a unified install for all subcloud
|
|
# 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
|
|
#
|
|
# Kickstart Early - Common Functions Script
|
|
# Pre Partition - Pre Disk Setup Common Script
|
|
# Partition - Partition Disks
|
|
# Mkfs - Format Partitions & LVM Volumes
|
|
# Post - Traits & Platform Config File update
|
|
# Post - Persistent Interface Setup
|
|
# Post - Set Kernel Args
|
|
# Post - Interface Setup
|
|
# Post Nochroot - Kickstart Finalize Install UUID
|
|
# Post Nochroot - Restage OSTree repo
|
|
# - Save Install Scripts and Logs
|
|
# Post - Log Filesystem Setup
|
|
# Post Nochroot - Workarounds for enabling integration
|
|
# Post Nochroot - Set up filesystems access
|
|
# Post Nochroot - Set up package links per node type
|
|
#
|
|
###########################################################################
|
|
#
|
|
# The first kickstart script creates '/tmp/lat/functions' common functions
|
|
# file that can be loaded from any of the other hook sections.
|
|
#
|
|
############################################################################
|
|
#
|
|
# Developer Note:
|
|
#
|
|
# The Linux Assembly Tool parses this kickstart file which contains
|
|
# various hook segments that are syntactically delineated with
|
|
# statements that start with '%'.
|
|
# The example below shows the start and end syntax of a hook block.
|
|
#
|
|
# %post --interpreter=/bin/bash --nochroot
|
|
#
|
|
# <kickstart bash code goes here>
|
|
#
|
|
# %end
|
|
#
|
|
# Warning: If LAT detects a hook block syntax error it fails the
|
|
# install and renders it as a Permission error console output like this.
|
|
#
|
|
# ./lat-installer.sh: line 539:
|
|
# /tmp/lat/lat_post_nochroot_script/10_script: Permission denied
|
|
#
|
|
# This may occur if for example %end is miss spelled as %en or missing
|
|
# or if the last %end is not terminated with a Line Feed.
|
|
#
|
|
###########################################################################
|
|
# 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}/miniboot.log"
|
|
|
|
############################################################################
|
|
# log utils
|
|
############################################################################
|
|
function log()
|
|
{
|
|
local dt="\$(date "+%Y-%m-%d %H:%M:%S.%3N")"
|
|
echo "\$dt miniboot \${HOOK_LABEL} info: \${prefix} \$1" >>\${LOGFILE}
|
|
}
|
|
|
|
function ilog()
|
|
{
|
|
[ -z "\${stdout}" ] && stdout=1
|
|
local dt="\$(date "+%Y-%m-%d %H:%M:%S.%3N")"
|
|
echo "\$dt miniboot \${HOOK_LABEL} info: \${prefix} \$1" >&\${stdout}
|
|
echo "\$dt miniboot \${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 miniboot \${HOOK_LABEL} debug: \${prefix} \$1" >&\${stdout}
|
|
echo "\$dt miniboot \${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 miniboot \${HOOK_LABEL} warn: \${prefix} \$1" >&\${stdout}
|
|
echo "\$dt miniboot \${HOOK_LABEL} warn: \${prefix} \$1" >>\${LOGFILE}
|
|
}
|
|
|
|
function elog()
|
|
{
|
|
[ -z "\$stdout" ] && stdout=1
|
|
local dt="\$(date "+%Y-%m-%d %H:%M:%S.%3N")"
|
|
echo "\$dt miniboot \${HOOK_LABEL} error: \${prefix} \$1" >&\${stdout}
|
|
echo "\$dt miniboot \${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 - any disk path
|
|
# Returns : echo of the canonicalized version of the disk path
|
|
#
|
|
# Example : /dev/sda -> /dev/sda
|
|
# : /dev/nvme1n1 -> /dev/nvme1n1
|
|
# : /dev/disk/by-path/pci-0000:02:00.0-scsi-0:1:0:0 -> /dev/sda
|
|
# : /dev/disk/by-id/wwn-0x50014ee6ae58b07f -> /dev/sdc
|
|
# : /dev/disk/by-id/wwn-0x600508b1001c2a30 -> /dev/dm-0
|
|
#########################################################################
|
|
function get_disk()
|
|
{
|
|
echo "\$(cd /dev ; readlink -f \$1)"
|
|
}
|
|
|
|
#########################################################################
|
|
# Name : get_persistent_disk
|
|
# Parameters: \$1 - device name i.e. /dev/sda
|
|
# Returns : echo of device name by-path or by-id
|
|
# example: /dev/disk/by-path/pci-0000:03:00.0-scsi-0:2:0:0 or
|
|
# /dev/disk/by-id/wwn-0x50014ee6ae58b07f
|
|
#
|
|
# Notes: During kickstarts there are 2 links to a generic /dev/sd<X>.
|
|
# Example: pci-0000:00:1f.2-ata-1 and pci-0000:00:1f.2-ata-1.0.
|
|
# After reboot only the longer 'ata-1.0' exists.
|
|
# Reverse the parsing so we return the longer path.
|
|
#########################################################################
|
|
function get_persistent_disk()
|
|
{
|
|
local dev=\$(cd /dev ; readlink -f \$1)
|
|
case \$dev in
|
|
*"dm-"*)
|
|
for p in /dev/disk/by-id/wwn-*; do
|
|
if [ "\$(basename \$dev)" = "\$(basename \$(readlink -f \$p))" ]; then
|
|
echo "\$p"
|
|
return
|
|
fi
|
|
done
|
|
;;
|
|
*)
|
|
reverse_list=""
|
|
for p in /dev/disk/by-path/*; do
|
|
reverse_list="\${p} \${reverse_list}"
|
|
done
|
|
for p in \${reverse_list}; do
|
|
if [ "\$(basename \$dev)" = "\$(basename \$(readlink -f \$p))" ]; then
|
|
echo "\$p"
|
|
return
|
|
fi
|
|
done
|
|
;;
|
|
esac
|
|
}
|
|
|
|
#########################################################################
|
|
# Name : get_part_prefix
|
|
# Parameters: \$1 - device name i.e. /dev/sda, /dev/nvme0n1, /dev/dm-0
|
|
# Returns : echo of acceptable partition prefix
|
|
# example: /dev/sda
|
|
# /dev/nvme0n1p
|
|
# /dev/disk/by-id/wwn-0x50014ee6ae58b07f-part
|
|
#########################################################################
|
|
function get_part_prefix()
|
|
{
|
|
# ensure that we have a canonicalized device
|
|
local dev=\$(cd /dev ; readlink -f \$1)
|
|
case \$dev in
|
|
*"nvme"*)
|
|
echo "\${dev}p"
|
|
;;
|
|
*"dm-"*)
|
|
for p in /dev/disk/by-id/wwn-*; do
|
|
if [ "\$dev" = "\$(readlink -f \$p)" ]; then
|
|
echo "\${p}-part"
|
|
return
|
|
fi
|
|
done
|
|
;;
|
|
*)
|
|
echo "\${dev}"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
#########################################################################
|
|
# 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_miniboot
|
|
# Returns : true : 0 if this is remote subcloud install (redfish)
|
|
# false: 1
|
|
#########################################################################
|
|
function is_miniboot()
|
|
{
|
|
if [ "\$(grep -c 'ip=' /proc/cmdline)" -ne 0 ]; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
#########################################################################
|
|
# Name : is_system_node_install
|
|
# Returns : true : 0 if 'pxecontroller' is in $insturl boot arg
|
|
# false: 1
|
|
#########################################################################
|
|
function is_system_node_install()
|
|
{
|
|
# minboot: always false
|
|
return 1
|
|
}
|
|
|
|
#########################################################################
|
|
# Name : is_usb_install
|
|
# Returns : true :0
|
|
# false:1
|
|
#########################################################################
|
|
function is_usb_install()
|
|
{
|
|
# minboot: always false
|
|
return 1
|
|
}
|
|
|
|
#########################################################################
|
|
# Name : check_prestage
|
|
# Returns : true :0
|
|
# false:1
|
|
#########################################################################
|
|
function check_prestage()
|
|
{
|
|
# minboot: always false
|
|
return 1
|
|
}
|
|
|
|
#########################################################################
|
|
# Name : is_prestage
|
|
# Returns : true :0
|
|
# false:1
|
|
#########################################################################
|
|
function is_prestage()
|
|
{
|
|
# minboot: always false
|
|
return 1
|
|
}
|
|
#########################################################################
|
|
# 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 ()
|
|
{
|
|
local msg=\${1}
|
|
local conf=\${2}
|
|
lvm_global_filter=\$(cat \${conf} | grep "global_filter =")
|
|
lvm_preferred_names=\$(cat \${conf} | grep "preferred_names =")
|
|
|
|
ilog "\${msg}: \${conf}: \${lvm_global_filter}"
|
|
ilog "\${msg}: \${conf}: \${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 partition, physical volume, and logical volume sizes
|
|
# Parameter: None
|
|
# Return : Nothing, but exports key values
|
|
#########################################################################
|
|
function get_aio_controller_provisioning_sizes()
|
|
{
|
|
gib=\$((1024*1024*1024))
|
|
|
|
# Partitions
|
|
export PART_SZ_EFI=300
|
|
export PART_SZ_BOOT=2048
|
|
export PART_SZ_ROOT=0
|
|
|
|
# Logical volumes
|
|
export LV_SZ_LOG=8000
|
|
export LV_SZ_ROOT=20480
|
|
export LV_SZ_SCRATCH=16000
|
|
export LV_SZ_VAR=20480
|
|
|
|
##
|
|
## 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
|
|
## LV_SZ_LOG = 8GiB
|
|
## LV_SZ_ROOT = 20 GiB
|
|
## LV_SZ_SCRATCH = 16GiB
|
|
## LV_SZ_VAR = 20 GiB
|
|
## 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 + 20 + 16 + 20 + 2 + 1 + 30 + 16 + 5 + 20 + 10 + 15)GiB + 16MiB/1024 = 218.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
|
|
##
|
|
## LV_SZ_LOG = 8GiB
|
|
## LV_SZ_SCRATCH = 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
|
|
##
|
|
## LV_SZ_LOG = 3GiB
|
|
## LV_SZ_SCRATCH = 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 + PART_SZ_ROOT + PART_SZ_EFI + PART_SZ_BOOT + FLUXDATA + 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 \${INSTDEV} has size:\${sz}B, \$((\${sz}/\$gib))GiB"
|
|
|
|
# Round MINIMUM_PLATFORM_PV_SIZE to the closest upper value that can be divided by 1024.
|
|
if [ \${sz} -gt \$((\${default_small_disk_size}*\${gib})) ] ; then
|
|
ilog "Large disk: MINIMUM_PLATFORM_PV_SIZE=219GiB*1024=224256 MiB"
|
|
export BACKUP_DEFAULT_PERSISTENT_SIZE=30000
|
|
elif [ \${sz} -ge \$((\${minimum_small_disk_size}*\${gib})) ] ; then
|
|
ilog "Small disk: MINIMUM_PLATFORM_PV_SIZE=164GiB*1024=167936 MiB"
|
|
export BACKUP_DEFAULT_PERSISTENT_SIZE=30000
|
|
else
|
|
ilog "Tiny disk: MINIMUM_PLATFORM_PV_SIZE=43GiB*1024=44032 MiB"
|
|
# Using a disk with a size under 85GiB will fail.
|
|
export LV_SZ_LOG=3000
|
|
export LV_SZ_SCRATCH=2000
|
|
export BACKUP_DEFAULT_PERSISTENT_SIZE=1000
|
|
fi
|
|
}
|
|
|
|
#########################################################################
|
|
# Name : get_std_controller_provisioning_sizes
|
|
# Purpose : Provide partition, physical volume, and logical volume sizes
|
|
# Parameter: None
|
|
# Return : Nothing, but exports key values
|
|
#########################################################################
|
|
function get_std_controller_provisioning_sizes()
|
|
{
|
|
|
|
## NOTE: updates to partition sizes need to be also reflected in
|
|
## _controller_filesystem_limits() in sysinv/api/controllers/v1/istorconfig.py
|
|
|
|
# Partitions
|
|
export PART_SZ_EFI=300
|
|
export PART_SZ_BOOT=2048
|
|
export PART_SZ_ROOT=0
|
|
export BACKUP_DEFAULT_PERSISTENT_SIZE=30000
|
|
|
|
# Logical volumes
|
|
export LV_SZ_LOG=8000
|
|
export LV_SZ_ROOT=20480
|
|
export LV_SZ_SCRATCH=16000
|
|
export LV_SZ_VAR=20480
|
|
|
|
}
|
|
#########################################################################
|
|
# Name : get_worker_provisioning_sizes
|
|
# Purpose : Provide partition, physical volume, and logical volume sizes
|
|
# Parameter: None
|
|
# Return : Nothing, but exports key values
|
|
#########################################################################
|
|
function get_worker_provisioning_sizes()
|
|
{
|
|
# miniboot: unused
|
|
ilog get_worker_provisioning_sizes
|
|
}
|
|
|
|
#########################################################################
|
|
# Name : get_storage_provisioning_sizes
|
|
# Purpose : Provide partition, physical volume, and logical volume sizes
|
|
# Parameter: None
|
|
# Return : Nothing, but exports key values
|
|
#########################################################################
|
|
function get_storage_provisioning_sizes()
|
|
{
|
|
# miniboot: unused
|
|
ilog get_storage_provisioning_sizes
|
|
}
|
|
|
|
#########################################################################
|
|
# Name : parse_miniboot_network_params
|
|
# Purpose : Setup IP addressing for two cases:
|
|
# 1) initial boot and 2) persistent across reboot
|
|
# Parameter: operation: one of 'initial' or 'persistent'
|
|
# Return : Nothing
|
|
#########################################################################
|
|
function parse_miniboot_network_params()
|
|
{
|
|
BOOTPARAM_MGMT_ADDRESS_FAMILY=
|
|
BOOTPARAM_IP_ADDR=
|
|
BOOTPARAM_VLAN=
|
|
BOOTPARAM_GW=
|
|
BOOTPARAM_PREFIX_LEN=
|
|
BOOTPARAM_IFNAME=
|
|
BOOTPARAM_IP_VER=
|
|
BOOTPARAM_METRIC=
|
|
BOOTPARAM_DNS=
|
|
|
|
# Parse values from /proc/cmdline
|
|
local ipstring=
|
|
local vlan=
|
|
for arg in \$(cat /proc/cmdline); do
|
|
case "\${arg}" in
|
|
ip=*)
|
|
ipstring=\${arg:3}
|
|
ilog "Using ip=\$ipstring"
|
|
;;
|
|
vlan=*)
|
|
vlan=\${arg:5}
|
|
ilog "Using vlan=\${vlan}"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
ilog "Parsing boot ipstring=\$ipstring"
|
|
|
|
# Now we have a string like:
|
|
# <client-ip>,,<gw-ip>,<prefixlen>,<hostname>,<device>,off,<dns0-ip>,<dns1-ip>
|
|
# 1 2 3 4 5 6 7 8 9
|
|
# identify if ipv4 or ipv6, and get the ip address
|
|
#
|
|
# 10.10.10.22,,10.10.10.1,23,subcloud2,enp2s1,none (for ipv4)
|
|
# [2620:10a:a001:d41::212],,,64,subcloud3,ens1f0.401,none (for ipv6)
|
|
|
|
BOOTPARAM_IP_ADDR=\$(echo \$ipstring | awk -F',' '{print \$1}' | tr -d '\[\]')
|
|
BOOTPARAM_GW=\$(echo \$ipstring | awk -F',' '{print \$3}' | tr -d '\[\]')
|
|
BOOTPARAM_PREFIX_LEN=\$(echo \$ipstring | awk -F',' '{print \$4}')
|
|
hostname=\$(echo \$ipstring | awk -F',' '{print \$5}')
|
|
BOOTPARAM_IFNAME=\$(echo \$ipstring | awk -F',' '{print \$6}')
|
|
# Do not setup DNS for now - we use IP addresses during boot:
|
|
# BOOTPARAM_DNS=\$(echo \$ipstring | awk -F',' '{print \$8}')
|
|
|
|
case "\$ipstring" in
|
|
*'['*)
|
|
# if has [ ] then it is ipv6:
|
|
BOOTPARAM_MGMT_ADDRESS_FAMILY="inet6"
|
|
BOOTPARAM_IP_VER="-6"
|
|
BOOTPARAM_METRIC="metric 1"
|
|
;;
|
|
*)
|
|
BOOTPARAM_MGMT_ADDRESS_FAMILY="inet"
|
|
;;
|
|
esac
|
|
|
|
if [ -n "\${vlan}" ]; then
|
|
# Parameter format: "bootstrap_interface.bootstrap_vlan:bootstrap_interface"
|
|
dlog "Parsing vlan from \${vlan}"
|
|
vlan=\${vlan#*.} # remove prefix 'bootstrap_interface.'
|
|
vlan=\${vlan%:*} # remove suffix ':bootstrap_interface'
|
|
BOOTPARAM_VLAN=\${vlan}
|
|
BOOTPARAM_IFNAME=\${BOOTPARAM_IFNAME%.*} # remove suffix '.bootstrap_vlan'
|
|
fi
|
|
|
|
logmsg="Using IP values: ip:\$BOOTPARAM_IP_ADDR, family: \$BOOTPARAM_MGMT_ADDRESS_FAMILY"
|
|
if [ -n "\$BOOTPARAM_VLAN" ]; then
|
|
logmsg="\$logmsg vlan: \$BOOTPARAM_VLAN, "
|
|
fi
|
|
logmsg="\$logmsg prefix:\$BOOTPARAM_PREFIX_LEN, ifname: \$BOOTPARAM_IFNAME, "
|
|
if [ -n "\${BOOTPARAM_GW}" ]; then
|
|
logmsg="\$logmsg gw:\$BOOTPARAM_GW, "
|
|
fi
|
|
logmsg="\$logmsg metric: \$BOOTPARAM_METRIC, dns: \$BOOTPARAM_DNS"
|
|
ilog "\$logmsg"
|
|
|
|
export BOOTPARAM_MGMT_ADDRESS_FAMILY
|
|
export BOOTPARAM_IP_ADDR
|
|
export BOOTPARAM_VLAN
|
|
export BOOTPARAM_GW
|
|
export BOOTPARAM_PREFIX_LEN
|
|
export BOOTPARAM_IFNAME
|
|
export BOOTPARAM_IP_VER
|
|
export BOOTPARAM_METRIC
|
|
export BOOTPARAM_DNS
|
|
}
|
|
|
|
#########################################################################
|
|
# Name : wait_for_interface
|
|
# Purpose : Wait for interface to settle
|
|
# Parameter: interface name
|
|
# Return : Nothing
|
|
#########################################################################
|
|
function wait_for_interface()
|
|
{
|
|
local ifname=\$1
|
|
local timeout=\${2:-60}
|
|
local operstate=
|
|
local count_sec=0
|
|
ilog "Waiting for interface \${ifname} to settle... [timeout: \${timeout}s]"
|
|
while [ \${count_sec} -lt \${timeout} ]; do
|
|
sleep 1
|
|
if [ -e /sys/class/net/\${mgmt_dev}/operstate ]; then
|
|
operstate=\$(cat /sys/class/net/\${mgmt_dev}/operstate)
|
|
if [ "\$operstate" = up ]; then
|
|
ilog "\${mgmt_dev} operstate: up"
|
|
return
|
|
fi
|
|
dlog "\${mgmt_dev} operstate: \$operstate"
|
|
fi
|
|
count_sec=\$(( count_sec + 1 ))
|
|
done
|
|
case "\$operstate" in
|
|
unknown)
|
|
# see: https://www.kernel.org/doc/Documentation/networking/operstates.txt
|
|
wlog "Timeout: \${mgmt_dev} operstate: unknown. Allowing boot to continue."
|
|
return
|
|
;;
|
|
*)
|
|
report_failure_with_msg "Timeout waiting for interface \${ifname} to settle; operstate: \$operstate"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
##########################################################################
|
|
# Global Kickstart Constants #
|
|
##########################################################################
|
|
#
|
|
# NOTE: exported Variables from other segments are NOT visible from functions
|
|
#
|
|
|
|
# Log the server firmware type
|
|
if [ -d /sys/firmware/efi ] ; then
|
|
ilog "UEFI Firmware execution"
|
|
USE_UEFI_PARTITIONS=1
|
|
else
|
|
ilog "BIOS Firmware execution"
|
|
USE_UEFI_PARTITIONS=0
|
|
fi
|
|
|
|
if [ "\${controller}" = true ] ; then
|
|
# Legacy locations of the backup partition
|
|
BACKUP_PART_UEFI=1
|
|
BACKUP_PART_BIOS=2
|
|
|
|
# Set the expected locations of the backup partition
|
|
if [ "\$USE_UEFI_PARTITIONS" = 0 ] ; then
|
|
BACKUP_PART_NO=\${BACKUP_PART_BIOS}
|
|
else
|
|
BACKUP_PART_NO=\${BACKUP_PART_UEFI}
|
|
fi
|
|
BACKUP_PART_LABEL="platform_backup"
|
|
|
|
# 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"
|
|
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=""
|
|
|
|
# Assume there is no Platform Backup (persistent) Partition
|
|
export BACKUP_PART_FOUND=0
|
|
export BACKUP_PART_CURRENT_SIZE=0
|
|
|
|
export STOR_DEV_FDS=""
|
|
|
|
export PROC_SELF_FDS="$(ls -1 /proc/$$/fd | egrep -v "^(0|1|2|255)$" | xargs)"
|
|
for fd in ${PROC_SELF_FDS}; do
|
|
export realpath=$(readlink -f /proc/$$/fd/"${fd}")
|
|
if [ -e "${realpath}" ]; then
|
|
STOR_DEV_FDS="${STOR_DEV_FDS} ${fd}"
|
|
fi
|
|
done
|
|
|
|
##########################################################################
|
|
# Local Kickstart variables #
|
|
##########################################################################
|
|
BACKUP_PART_FIRST=0
|
|
BACKUP_PART_END=0
|
|
BACKUP_PART_SIZE=0
|
|
BACKUP_PART_FLAGS=0
|
|
BACKUP_PART_NAME=""
|
|
|
|
##########################################################################
|
|
|
|
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
|
|
report_failure_with_msg "Invalid miniboot subcloud traits: $traits"
|
|
elif [ "${storage}" = true ] ; then
|
|
report_failure_with_msg "Invalid miniboot subcloud traits: $traits"
|
|
fi
|
|
if [ "${lowlatency}" = true ] ; then
|
|
prefix="${prefix}-${TRAIT__LOWLATENCY}"
|
|
fi
|
|
|
|
grep -q 'debug_kickstart' /proc/cmdline
|
|
if [ $? -eq 0 ]; then
|
|
debug=1
|
|
fi
|
|
|
|
# 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
|
|
|
|
# Handle persistent_size setting.
|
|
# If the persistent_size is less than the size of the existing persistent backup,
|
|
# then the installation process must terminate and exit.
|
|
|
|
if [ -n "${persistent_size}" ]; then
|
|
part=$(readlink -f "/dev/disk/by-partlabel/platform_backup")
|
|
device=$(readlink -f "${rootfs_device}")
|
|
|
|
ilog "Persistent backup is in ${part}"
|
|
|
|
MAX_SIZE=$(parted -s ${device} unit MiB print | grep "Disk ${device}:" | awk '{print $3}' | sed 's/[^C0-9]*//g')
|
|
CURRENT_PERSISTENT_SIZE=$(parted -s ${part} unit MiB print | grep ${part} | awk '{print $3}' | sed 's/[^C0-9]*//g')
|
|
ilog "Current size of persistent backup is ${CURRENT_PERSISTENT_SIZE}"
|
|
ilog "Max size of ${device} is ${MAX_SIZE}"
|
|
|
|
if [ ${persistent_size} -lt ${CURRENT_PERSISTENT_SIZE} ]; then
|
|
ilog "Provided persistent_size (${persistent_size}) is less than ${CURRENT_PERSISTENT_SIZE}"
|
|
report_failure_with_msg "Persistent size setting is less than current backup size (${CURRENT_PERSISTENT_SIZE})"
|
|
fi
|
|
|
|
if [ ${persistent_size} -gt ${MAX_SIZE} ]; then
|
|
ilog "Provided persistent_size (${persistent_size}) is greater than ${MAX_SIZE}"
|
|
report_failure_with_msg "Persistent size setting is greater than maximum allowable size (${MAX_SIZE})"
|
|
fi
|
|
fi
|
|
|
|
# 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'"
|
|
|
|
# We need both the system date and hwclock to be "close" to the current
|
|
# date/time, in order to avoid cases of invalid SSL certificates during
|
|
# interaction with the system controller. With the 'instdate'
|
|
# boot paramter, the system clock will already be initialized by LAT.
|
|
# If the hwclock differs from system date by a significant amount then
|
|
# we update it here based on the current system date.
|
|
#
|
|
# System date initialization summary:
|
|
# Note: NTP is not running at these early stages of install
|
|
#
|
|
# miniboot:
|
|
# - The system date is initialized to 'instdate' via LAT.
|
|
# Note that this may be several minutes out of sync with reality
|
|
# since instdate is a snapshot at time of bootimage.iso creation.
|
|
#
|
|
# ostree boot (after miniboot, prior to subcloud bootstrap):
|
|
# - The system date is initialized via hwclock.
|
|
#
|
|
# During miniboot we may have the case where the hwclock is more accurate
|
|
# than the system date. We therefore only want to adjust the hwclock if
|
|
# it is significantly different.
|
|
if [ -n "${instdate}" ]; then
|
|
ilog "Checking hwclock: $(hwclock), current date: $(date), instdate: $(date --date=${instdate})"
|
|
# Only adjust if date mismatch is > 20m
|
|
date_mismatch_threshold_secs=1200
|
|
current_date_epoch=$(date "+%s")
|
|
hwclock_date_epoch=$(date --date="$(hwclock --get --utc)" "+%s")
|
|
diff_epoch=$(( current_date_epoch - hwclock_date_epoch ))
|
|
# absolute value: strip off any '-' from front of string:
|
|
abs_diff_epoch=${diff_epoch#-}
|
|
if [ ${abs_diff_epoch} -gt ${date_mismatch_threshold_secs} ]; then
|
|
if [ -e /sbin/hwclock ] ; then
|
|
ilog "Aligning hwclock to system date"
|
|
/sbin/hwclock --systohc --utc
|
|
if [ $? -ne 0 ]; then
|
|
wlog "failed hwclock command ; /sbin/hwclock --systohc --utc [rc=${rc}]"
|
|
fi
|
|
else
|
|
wlog "lat initrd is missing /sbin/hwclock"
|
|
fi
|
|
ilog "System date is now: $(date), hwclock: $(hwclock)"
|
|
fi
|
|
else
|
|
elog "bootimage.iso was constructed without instdate: subcloud date may be out of sync"
|
|
fi
|
|
|
|
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
|
|
persistent_instdev=$(get_persistent_disk "${INSTDEV}")
|
|
if [ -z ${persistent_instdev} ] ; then
|
|
report_failure_with_msg "invalid install device ${INSTDEV}"
|
|
else
|
|
ilog "Install device: ${INSTDEV} : ${persistent_instdev}"
|
|
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:"
|
|
case ${persistent_instdev} in
|
|
*"by-id"*)
|
|
disk_regex='/dev/disk/by-id/wwn-*'
|
|
;;
|
|
*)
|
|
disk_regex='/dev/disk/by-path/*'
|
|
;;
|
|
esac
|
|
|
|
STOR_DEVS=""
|
|
for f in ${disk_regex} ; do
|
|
dev=$(readlink -f $f)
|
|
# dlog "found device ${f}"
|
|
exec_retry 2 0.5 "lsblk --nodeps --pairs $dev" | grep -q -e 'TYPE="disk"' -e 'TYPE="mpath"'
|
|
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
|
|
vgs=( $(exec_no_fds "$STOR_DEV_FDS" "vgdisplay -C --noheadings -o vg_uuid 2>/dev/null") )
|
|
if [ ${#vgs[@]} -eq 0 ] ; then
|
|
ilog "No volume groups found"
|
|
else
|
|
for vg in ${vgs[@]}; do
|
|
lvs=( $(exec_no_fds "$STOR_DEV_FDS" "lvs --select vg_uuid=${vg} --noheadings -o lv_name 2>/dev/null") )
|
|
vg_name=$(exec_no_fds "$STOR_DEV_FDS" "vgdisplay -C --noheadings --select vg_uuid=${vg} -o vg_name 2>/dev/null" | xargs)
|
|
|
|
ilog "Wipe any previous signatures from ${vg_name} volume group"
|
|
for lv in ${lvs[@]} ; do
|
|
ilog "Wipe any previous signatures from ${lv} logical volume"
|
|
exec_no_fds "$STOR_DEV_FDS" "wipefs -a /dev/${vg_name}/${lv} 2>/dev/null" 5 0.5 || wlog "Failed to wipe signatures from ${lv}"
|
|
done
|
|
|
|
ilog "Disable volume group ${vg}"
|
|
exec_no_fds "$STOR_DEV_FDS" "vgchange -an --select vg_uuid=${vg} 2>/dev/null" 5 0.5
|
|
[ $? -ne 0 ] && report_failure_with_msg "Failed to disable ${vg}."
|
|
done
|
|
|
|
for vg in ${vgs[@]}; do
|
|
vg_name=$(exec_no_fds "$STOR_DEV_FDS" "vgdisplay -C --noheadings --select vg_uuid=${vg} -o vg_name 2>/dev/null" | xargs)
|
|
|
|
pvs=( $(exec_no_fds "$STOR_DEV_FDS" "pvs --select vg_uuid=${vg} --noheadings -o pv_name 2>/dev/null" | grep -v unknown) )
|
|
if [ ${#pvs[@]} -ne 0 ] ; then
|
|
ilog "Remove logical volumes from ${vg_name} (${vg})"
|
|
exec_no_fds "$STOR_DEV_FDS" "lvremove --force --select vg_uuid=${vg} 2>/dev/null" 5 0.5 || wlog "WARNING: Failed to remove lvs on ${vg_name} (${vg})."
|
|
|
|
for pv in ${pvs[@]}; do
|
|
ilog "Remove physical volume ${pv} from ${vg_name} (${vg})"
|
|
exec_no_fds "$STOR_DEV_FDS" "pvremove --force --force --yes ${pv} 2>/dev/null" 5 0.5
|
|
[ $? -ne 0 ] && report_failure_with_msg "Failed to remove ${pv}."
|
|
done
|
|
fi
|
|
|
|
ilog "Force remove volume group ${vg_name} (${vg})"
|
|
exec_no_fds "$STOR_DEV_FDS" "vgremove --force --select vg_uuid=${vg} 2>/dev/null" 5 0.5
|
|
[ $? -ne 0 ] && report_failure_with_msg "Failed to remove ${vg_name} (${vg})."
|
|
|
|
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"
|
|
|
|
# The /v1/upgrade/${hostname}/in_upgrade endpoint accepts any textual data
|
|
# as hostname and returns system-wide upgrade state
|
|
hostname="hostname"
|
|
|
|
|
|
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_OSD_MPATH_GUID="4FBD7E29-8AE0-4982-BF9D-5A8D867AF560"
|
|
CEPH_JOURNAL_GUID="45B0969E-9B03-4F30-B4C6-B4B80CEFF106"
|
|
CEPH_JOURNAL_MPATH_GUID="45B0969E-8AE0-4982-BF9D-5A8D867AF560"
|
|
|
|
# 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"
|
|
|
|
# Check if the disk is Rook Ceph OSD
|
|
fs_type=$(blkid -o value -s TYPE "${dev}")
|
|
if [ "${fs_type}" == "ceph_bluestore" ]; then
|
|
wlog "BlueStore OSD found on $dev, skipping wipe"
|
|
wipe_dev="false"
|
|
else
|
|
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 -o "$part_type_guid" == $CEPH_OSD_MPATH_GUID ]; then
|
|
wlog "OSD found on $dev, skipping wipe"
|
|
wipe_dev="false"
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
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 "==========="
|
|
inst_dev=$(get_disk "${INSTDEV}")
|
|
for dev in ${WIPE_HDD//,/ } ; do
|
|
ilog "Wiping $dev"
|
|
|
|
# Check if the disk is Rook Ceph OSD
|
|
# see https://github.com/rook/rook/blob/master/Documentation/Storage-Configuration/ceph-teardown.md#zapping-devices
|
|
fs_type=$(blkid -o value -s TYPE "${dev}")
|
|
if [ "${fs_type}" == "ceph_bluestore" ]; then
|
|
sgdisk --zap-all "${dev}"
|
|
wipefs -a "${dev}"
|
|
continue
|
|
fi
|
|
|
|
# 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 device partition 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
|
|
if [ "${dev}" == "${inst_dev}" ] ; then
|
|
|
|
# Skip over the bios, efi and boot partitions that got us here.
|
|
# LAT handles these partitions
|
|
case ${part_name} in
|
|
"'bios'" | "'otaefi'" | "'otaboot'" | "'otaboot_b'")
|
|
ilog "skipping ${part_name} on partition ${part_number} of device ${dev}"
|
|
continue
|
|
;;
|
|
*)
|
|
dlog "wipe candidate ${part_name} on partition ${part_number} of device ${dev}"
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
part=$(get_part_prefix "${dev}")$part_number
|
|
if [ "${controller}" = true ] ; then
|
|
# Skip if we already found a valid partition, look otherwise
|
|
[ ${BACKUP_PART_FOUND} -eq 1 ] && continue
|
|
|
|
ilog "Looking for platform-backup partition on $part from ... instdev=${INSTDEV} device=${inst_dev} persistent_device=${persistent_instdev}"
|
|
sgdisk_part_info=$(sgdisk -i $part_number $dev)
|
|
part_type_guid=$(echo "$sgdisk_part_info" | grep "$part_type_guid_str" | awk '{print $4;}')
|
|
dlog "Examining part_number=${part_number}, by_dev=${by_dev}, dev=${dev}, part_type_guid: ${part_type_guid}"
|
|
dlog "sgdisk_part_info: ${sgdisk_part_info}"
|
|
dlog "BACKUP_PART_GUID: ${BACKUP_PART_GUID}"
|
|
if [ "$dev" == "${inst_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 "Discovered persistent backup partition: ${part} [${BACKUP_PART_NAME}:${BACKUP_PART_FIRST}:${BACKUP_PART_END}:${BACKUP_PART_SIZE}:${part_type_guid}]"
|
|
|
|
# Only keep a backup partition that is in the expected location
|
|
# and contains a proper filesystem
|
|
if [ "${part_number}" == "${BACKUP_PART_NO}" ] ; then
|
|
part_fstype=$(exec_retry 5 0.5 "blkid -s TYPE -o value $part")
|
|
if [ "${part_fstype}" == "ext4" ]; then
|
|
BACKUP_PART_CURRENT_SIZE=$(parted -s ${part} unit MiB print | grep ${part} | awk '{print $3}' | sed 's/[^C0-9]*//g')
|
|
BACKUP_PART_FOUND=1
|
|
ilog "Discovered persistent backup partition, ${part} [${BACKUP_PART_CURRENT_SIZE} MiB], is in the expected location and is formatted correctly. Maintaining..."
|
|
continue
|
|
else
|
|
ilog "Discovered persistent backup partition, ${part}, has a missing 'ext4' filesystem . Recreating..."
|
|
fi
|
|
else
|
|
# Make sure we only recreate the backup partition on systems that are
|
|
# known to be invalid. Detect a potential switch in BIOS vs. UEFI and
|
|
# exit with an appropriate message.
|
|
ilog "Discovered persistent backup partition, ${part}, is in an unexpected location. Expected on partition ${BACKUP_PART_NO}."
|
|
if [ "$USE_UEFI_PARTITIONS" = 0 ] ; then
|
|
# BIOS boot...
|
|
if [ "${part_number}" == "${BACKUP_PART_UEFI}" ] ; then
|
|
# Found a UEFI location for platform backup
|
|
report_failure_with_msg "BIOS booted system has a persistent backup partition in a UEFI expected location. Wipe disks or boot system in UEFI mode."
|
|
else
|
|
ilog "BIOS booted system has an invalid installation. Recreating "
|
|
fi
|
|
else
|
|
# UEFI boot...
|
|
if [ "${part_number}" == "${BACKUP_PART_BIOS}" ] ; then
|
|
# Found a BIOS location for platform backup
|
|
report_failure_with_msg "UEFI booted system has a persistent backup partition in a BIOS expected location. Wipe disks or boot system in BIOS mode."
|
|
else
|
|
ilog "UEFI booted system has an invalid installation. Recreating "
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
if [ "${WIPE_CEPH_OSDS}" = "true" ] && ([ "${part_type_guid}" = "${CEPH_JOURNAL_GUID}" ] || [ "${part_type_guid}" = "${CEPH_MPATH_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 "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_PART_FOUND} -eq 0 -o "${dev}" != "${inst_dev}" ] ; then
|
|
ilog "Creating disk label for $dev"
|
|
parted -s $dev mktable gpt
|
|
ilog "... done"
|
|
fi
|
|
done
|
|
|
|
ilog "Ensure any LAT installer root/boot partitions are zapped/wiped"
|
|
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
|
|
|
|
# If multi-drivers-switch= is in boot parameters then we need to revert the
|
|
# kernel modules to the legacy version. This is a workaround for the LAT
|
|
# /install script not supporting multi-drivers-switch
|
|
driver_version=
|
|
if grep -s -q '\smulti-drivers-switch=' /proc/cmdline ; then
|
|
for arg in $(cat /proc/cmdline); do
|
|
case "${arg}" in
|
|
multi-drivers-switch=*)
|
|
driver_version=${arg##*=}
|
|
break
|
|
;;
|
|
esac
|
|
done
|
|
# Only proceed if we have a valid driver_version
|
|
if [ -n "${driver_version}" ] && \
|
|
[ -f "/lib/modules/$(uname -r)/extra/ice-${driver_version}/ice.ko" ] && \
|
|
[ -f "/lib/modules/$(uname -r)/extra/i40e-${driver_version}/i40e.ko" ] && \
|
|
[ -f "/lib/modules/$(uname -r)/extra/iavf-${driver_version}/iavf.ko" ]; then
|
|
ilog "Found multi-drivers-switch: replacing ice/i40e/iavf with driver_version='${driver_version}'"
|
|
modprobe -r ice
|
|
modprobe -r i40e
|
|
modprobe -r iavf
|
|
sleep 2
|
|
insmod "/lib/modules/$(uname -r)/extra/ice-${driver_version}/ice.ko"
|
|
insmod "/lib/modules/$(uname -r)/extra/i40e-${driver_version}/i40e.ko"
|
|
insmod "/lib/modules/$(uname -r)/extra/iavf-${driver_version}/iavf.ko"
|
|
sleep 2
|
|
ilog "Finished multi-drivers-switch module replacement"
|
|
else
|
|
elog "Found multi-drivers-switch but no modules exist for driver_version='${driver_version}' (ignoring)"
|
|
fi
|
|
fi
|
|
|
|
ilog "Setting up initial IP address for ostree pull"
|
|
parse_miniboot_network_params
|
|
|
|
mgmt_dev=${BOOTPARAM_IFNAME}
|
|
mgmt_vlan=${BOOTPARAM_VLAN}
|
|
mgmt_address_family=${BOOTPARAM_MGMT_ADDRESS_FAMILY}
|
|
|
|
if [ -z "${mgmt_vlan}" ] ; then
|
|
# NO VLAN
|
|
if [ "$mgmt_address_family" = "inet" ]; then
|
|
ilog "ip ${BOOTPARAM_IP_VER} address add ${BOOTPARAM_IP_ADDR}/${BOOTPARAM_PREFIX_LEN} dev ${mgmt_dev}"
|
|
ip ${BOOTPARAM_IP_VER} address add ${BOOTPARAM_IP_ADDR}/${BOOTPARAM_PREFIX_LEN} dev ${mgmt_dev}
|
|
else
|
|
# BOOTPARAM_PREFIX_LEN should not be empty, but guard against it:
|
|
if [ -z "${BOOTPARAM_PREFIX_LEN}" ]; then
|
|
ilog "ip ${BOOTPARAM_IP_VER} address add ${BOOTPARAM_IP_ADDR} dev ${mgmt_dev}"
|
|
ip ${BOOTPARAM_IP_VER} address add ${BOOTPARAM_IP_ADDR} dev ${mgmt_dev}
|
|
else
|
|
ilog "ip ${BOOTPARAM_IP_VER} address add ${BOOTPARAM_IP_ADDR}/${BOOTPARAM_PREFIX_LEN} dev ${mgmt_dev}"
|
|
ip ${BOOTPARAM_IP_VER} address add ${BOOTPARAM_IP_ADDR}/${BOOTPARAM_PREFIX_LEN} dev ${mgmt_dev}
|
|
fi
|
|
fi
|
|
ilog "ip ${BOOTPARAM_IP_VER} link set dev ${mgmt_dev} up"
|
|
ip ${BOOTPARAM_IP_VER} link set dev ${mgmt_dev} up
|
|
|
|
if [ -z "${BOOTPARAM_GW}" ]; then
|
|
# No gateway
|
|
ilog "ip ${BOOTPARAM_IP_VER} route add default dev ${mgmt_dev} ${BOOTPARAM_METRIC}"
|
|
ip ${BOOTPARAM_IP_VER} route add default dev ${mgmt_dev} ${BOOTPARAM_METRIC}
|
|
else
|
|
ilog "Setting up default route:"
|
|
ilog "ip ${BOOTPARAM_IP_VER} route add default via ${BOOTPARAM_GW} dev ${mgmt_dev} ${BOOTPARAM_METRIC}"
|
|
ip ${BOOTPARAM_IP_VER} route add default via ${BOOTPARAM_GW} dev ${mgmt_dev} ${BOOTPARAM_METRIC}
|
|
fi
|
|
wait_for_interface ${mgmt_dev} 60
|
|
ilog "ip addr:"
|
|
ip addr show
|
|
ilog "ip route:"
|
|
ip ${BOOTPARAM_IP_VER} route show
|
|
|
|
else
|
|
# VLAN CONFIG
|
|
mgmt_iface=vlan${mgmt_vlan}
|
|
ilog "mgmt_dev=${mgmt_dev}"
|
|
ilog "mgmt_iface=vlan${mgmt_vlan}"
|
|
ilog "mgmt_address_family: ${mgmt_address_family}"
|
|
|
|
ilog "ip ${BOOTPARAM_IP_VER} link add link ${mgmt_dev} name $mgmt_iface type vlan id ${mgmt_vlan}"
|
|
ip ${BOOTPARAM_IP_VER} link add link ${mgmt_dev} name $mgmt_iface type vlan id ${mgmt_vlan}
|
|
|
|
if [ "${mgmt_address_family}" = "inet" ]; then
|
|
ilog "ip ${BOOTPARAM_IP_VER} address add ${BOOTPARAM_IP_ADDR}/${BOOTPARAM_PREFIX_LEN} dev ${mgmt_iface}"
|
|
ip ${BOOTPARAM_IP_VER} address add ${BOOTPARAM_IP_ADDR}/${BOOTPARAM_PREFIX_LEN} dev ${mgmt_iface}
|
|
else
|
|
# BOOTPARAM_PREFIX_LEN should not be empty, but guard against it:
|
|
if [ -z "${BOOTPARAM_PREFIX_LEN}" ]; then
|
|
ilog "ip ${BOOTPARAM_IP_VER} address add ${BOOTPARAM_IP_ADDR} dev ${mgmt_iface}"
|
|
ip ${BOOTPARAM_IP_VER} address add ${BOOTPARAM_IP_ADDR} dev ${mgmt_iface}
|
|
else
|
|
ilog "ip ${BOOTPARAM_IP_VER} address add ${BOOTPARAM_IP_ADDR}/${BOOTPARAM_PREFIX_LEN} dev ${mgmt_iface}"
|
|
ip ${BOOTPARAM_IP_VER} address add ${BOOTPARAM_IP_ADDR}/${BOOTPARAM_PREFIX_LEN} dev ${mgmt_iface}
|
|
fi
|
|
fi
|
|
ilog "ip ${BOOTPARAM_IP_VER} link set up dev ${mgmt_dev}"
|
|
ip ${BOOTPARAM_IP_VER} link set up dev ${mgmt_dev}
|
|
wait_for_interface ${mgmt_dev} 60
|
|
ilog "ip ${BOOTPARAM_IP_VER} link set up dev ${mgmt_iface}"
|
|
ip ${BOOTPARAM_IP_VER} link set up dev ${mgmt_iface}
|
|
wait_for_interface ${mgmt_iface} 60
|
|
|
|
if [ -z "${BOOTPARAM_GW}" ]; then
|
|
# No gateway
|
|
ilog "ip ${BOOTPARAM_IP_VER} route add default dev ${mgmt_iface} ${BOOTPARAM_METRIC}"
|
|
ip ${BOOTPARAM_IP_VER} route add default dev ${mgmt_iface} ${BOOTPARAM_METRIC}
|
|
else
|
|
ilog "Setting up default route:"
|
|
ilog "ip ${BOOTPARAM_IP_VER} route add default via ${BOOTPARAM_GW} dev ${mgmt_iface} ${BOOTPARAM_METRIC}"
|
|
ip ${BOOTPARAM_IP_VER} route add default via ${BOOTPARAM_GW} dev ${mgmt_iface} ${BOOTPARAM_METRIC}
|
|
fi
|
|
|
|
ilog "ip ${BOOTPARAM_IP_VER} addr:"
|
|
ip ${BOOTPARAM_IP_VER} addr show
|
|
ilog "ip ${BOOTPARAM_IP_VER} route:"
|
|
ip ${BOOTPARAM_IP_VER} route show
|
|
fi
|
|
|
|
# get the nameserver
|
|
local dns="none"
|
|
for e in \${dns}; do
|
|
echo "nameserver \${e}" > /etc/resolv.conf
|
|
done
|
|
|
|
true
|
|
%end
|
|
|
|
###########################################################################
|
|
|
|
%part --interpreter=/bin/bash
|
|
HOOK_LABEL=" part"
|
|
. /tmp/lat/ks_functions.sh
|
|
ilog "*****************************************"
|
|
ilog "*** Partition - Partition Disks ***"
|
|
ilog "*****************************************"
|
|
|
|
inst_dev=$(get_disk "${INSTDEV}")
|
|
|
|
###########################################################
|
|
# From pre_disk_controller.cfg
|
|
###########################################################
|
|
|
|
function check_partitioning_status() {
|
|
start_sec=$(($end_sec+1))
|
|
part_no=$((part_no+1))
|
|
if [ $start_sec -gt $last ] ; then
|
|
report_failure_with_msg "Disk is not big enough for requested layout (start_sec: $start_sec, last: $last)"
|
|
fi
|
|
}
|
|
|
|
if [ "$BIOSPLUSEFI" = 1 ] ; then
|
|
ilog "BIOSPLUSEFI=1 configuration is requested"
|
|
if [ "${controller}" = true -a "$USE_UEFI_PARTITIONS" = 1 ] ; then
|
|
ilog "WARNING: UEFI booted and installed controllers will NOT have a BIOS MBR partition due to partitioning patterns established in previous releases."
|
|
fi
|
|
fi
|
|
|
|
MIB_BYTES=$((1024*1024))
|
|
|
|
# Start common partitioning regardless of personality
|
|
sgdisk_parts=""
|
|
|
|
# Get the logical sector size used for determining partition boundaries
|
|
LOGICAL_SECTOR_SZ=`lsblk -n ${inst_dev} -o LOG-SEC -d`
|
|
|
|
# Zap the GPT/MBR information
|
|
sgdisk -Z ${inst_dev}
|
|
|
|
# Get the first aligned sector
|
|
first=`sgdisk -F ${inst_dev} | grep -v Creating`
|
|
|
|
# Get the last aligned sector
|
|
export last=$(sgdisk -E ${inst_dev} 2>/dev/null |grep -v Creating)
|
|
|
|
ilog "Allocate host partitions on ${inst_dev} with first sector: $first and last sector: $last"
|
|
|
|
# Maintain BIOS partition mappings from previous releases
|
|
start_sec=$first
|
|
part_no=1
|
|
if [ "$USE_UEFI_PARTITIONS" = 0 -o "${controller}" = false ] ; then
|
|
# 1MB size for BIOS boot partition
|
|
BIOSSZ=1
|
|
end_sec=$(($start_sec+(${BIOSSZ}*${MIB_BYTES}/${LOGICAL_SECTOR_SZ})-1))
|
|
sgdisk_parts="$sgdisk_parts -n $part_no:$start_sec:$end_sec -c $part_no:bios -t $part_no:EF02"
|
|
check_partitioning_status
|
|
fi
|
|
|
|
if [ "${controller}" = true ] ; then
|
|
if [ "${aio}" = true ] ; then
|
|
get_aio_controller_provisioning_sizes
|
|
ilog "AIO Controller: MINIMIZING root disk space allocation"
|
|
else
|
|
get_std_controller_provisioning_sizes
|
|
ilog "STD Controller: MAXIMIZING root disk space allocation"
|
|
fi
|
|
|
|
# Only controllers have a persistent backup partition
|
|
# Use current partition size if it has been detected
|
|
if [ ${BACKUP_PART_CURRENT_SIZE} -gt 0 ]; then
|
|
BACKUP_SIZE=${BACKUP_PART_CURRENT_SIZE}
|
|
else
|
|
BACKUP_SIZE=${BACKUP_DEFAULT_PERSISTENT_SIZE}
|
|
fi
|
|
export BACKUP_SIZE
|
|
|
|
# Check for a bootline override and allocate platform backup partition
|
|
if [ -z "$persistent_size" ]; then
|
|
# Default backup partition size in MiB
|
|
ilog "Platform Backup persistent size not on command line ; defaulting to ${BACKUP_SIZE}"
|
|
else
|
|
ilog "Using Platform Backup persistent size from boot command: ${persistent_size}"
|
|
BACKUP_SIZE=${persistent_size}
|
|
fi
|
|
backup_part_extension_required=0
|
|
if [ ${BACKUP_PART_CURRENT_SIZE} -gt 0 ]; then
|
|
# Reconcile current backup partition size against BACKUP_SIZE
|
|
if [ ${BACKUP_SIZE} -eq ${BACKUP_PART_CURRENT_SIZE} ] ; then
|
|
ilog "Platform Backup partition size is unchanged: ${BACKUP_SIZE} MiB."
|
|
elif [ ${BACKUP_SIZE} -gt ${BACKUP_PART_CURRENT_SIZE} ] ; then
|
|
# We need to extend the existing partition - this is done after the partitions are recreated
|
|
backup_part_extension_required=1
|
|
else
|
|
# Do not allow shrinking of backup partition
|
|
report_failure_with_msg "Cannot shrink platform backup smaller than existing ${BACKUP_PART_CURRENT_SIZE} MiB"
|
|
fi
|
|
fi
|
|
ilog "Platform Backup partition size: ${BACKUP_SIZE}"
|
|
|
|
if [ ${BACKUP_PART_FOUND} -eq 0 ] ; then
|
|
ilog "Platform Backup partition not detected: CREATING"
|
|
else
|
|
ilog "Platform Backup Partition was detected: PERSISTING"
|
|
fi
|
|
dlog "BACKUP_SIZE=${BACKUP_SIZE} after persistent_size=${persistent_size}, backup_part_extension_required=${backup_part_extension_required}"
|
|
|
|
end_sec=$(($start_sec+(${BACKUP_SIZE}*${MIB_BYTES}/${LOGICAL_SECTOR_SZ})-1))
|
|
sgdisk_parts="$sgdisk_parts -n $part_no:$start_sec:$end_sec -c $part_no:${BACKUP_PART_LABEL} -t $part_no:${BACKUP_PART_GUID}"
|
|
check_partitioning_status
|
|
|
|
elif [ "${worker}" = true ] ; then
|
|
ilog "Setting up platform_pv partition sizes for worker node"
|
|
get_worker_provisioning_sizes
|
|
elif [ "${storage}" = true ] ; then
|
|
ilog "Setting up platform_pv partition sizes for storage node"
|
|
get_storage_provisioning_sizes
|
|
fi
|
|
|
|
ilog "PART_SZ_EFI : ${PART_SZ_EFI}"
|
|
ilog "PART_SZ_BOOT : ${PART_SZ_BOOT}"
|
|
ilog "PART_SZ_ROOT : ${PART_SZ_ROOT}"
|
|
|
|
# 300 MiB size for EFI boot partition to align with previous releases
|
|
end_sec=$(($start_sec+(${PART_SZ_EFI}*${MIB_BYTES}/${LOGICAL_SECTOR_SZ})-1))
|
|
sgdisk_parts="$sgdisk_parts -n $part_no:$start_sec:$end_sec -c $part_no:otaefi -t $part_no:EF00"
|
|
check_partitioning_status
|
|
|
|
# Boot/Root OSTree Partition A (Note: OSTree Partition B not used)
|
|
if [ "${PART_SZ_BOOT}" != 0 ] ; then
|
|
end_sec=$(($start_sec+(${PART_SZ_BOOT}*${MIB_BYTES}/${LOGICAL_SECTOR_SZ})-1))
|
|
sgdisk_parts="$sgdisk_parts -n $part_no:$start_sec:$end_sec -c $part_no:otaboot"
|
|
check_partitioning_status
|
|
fi
|
|
|
|
if [ "${PART_SZ_ROOT}" != 0 ] ; then
|
|
if [ "$INSTAB" = 0 -a "${INSTFLUX}" = 0 ] ; then
|
|
if [ "$VSZ" = 0 ] ; then
|
|
report_failure_with_msg "Installation with VSZ=0 is not supported."
|
|
else
|
|
end_sec=$(($start_sec+(${PART_SZ_ROOT}*${MIB_BYTES}/${LOGICAL_SECTOR_SZ})-1))
|
|
fi
|
|
sgdisk_parts="$sgdisk_parts -n $part_no:$start_sec:$end_sec -c $part_no:otaroot"
|
|
else
|
|
end_sec=$(($start_sec+(${PART_SZ_ROOT}*${MIB_BYTES}/${LOGICAL_SECTOR_SZ})-1))
|
|
sgdisk_parts="$sgdisk_parts -n $part_no:$start_sec:$end_sec -c $part_no:otaroot"
|
|
fi
|
|
check_partitioning_status
|
|
fi
|
|
|
|
# Flux Partition
|
|
if [ "${LV_SZ_VAR}" = 0 -a "${INSTFLUX}" = 1 ] ; then
|
|
if [ "$VSZ" = 0 ] ; then
|
|
report_failure_with_msg "Installation with VSZ=0 is not supported."
|
|
else
|
|
end_sec=$(($start_sec+(${VSZ}*${MIB_BYTES}/${LOGICAL_SECTOR_SZ})-1))
|
|
fi
|
|
sgdisk_parts="$sgdisk_parts -n $part_no:$start_sec:$end_sec -c $part_no:fluxdata"
|
|
check_partitioning_status
|
|
fi
|
|
|
|
# Allocate platform pv
|
|
ilog "platform_pv partition - using all remaining disk space"
|
|
end_sec=$last
|
|
sgdisk_parts="$sgdisk_parts -n $part_no:$start_sec:$end_sec -c $part_no:platform_pv -t $part_no: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"
|
|
|
|
# CREATE PARTITIONS
|
|
dlog "Requesting ${inst_dev} Partition Table: ${a}"
|
|
dlog "Executing: sgdisk ${sgdisk_parts} -p ${inst_dev}"
|
|
sgdisk $sgdisk_parts -p ${inst_dev}
|
|
rc=$?
|
|
[ ${rc} -ne 0 ] && report_failure_with_msg "sgdisk failed to create partitions: ${a} [rc=${rc}]"
|
|
|
|
if [ "${backup_part_extension_required}" -ne 0 ]; then
|
|
instdev_part_prefix=$(get_part_prefix "${inst_dev}")
|
|
# The backup partition has been increased via persistent_size.
|
|
# Extend the partition and resize the FS
|
|
wlog "Platform Backup partition: resizing ${instdev_part_prefix}${BACKUP_PART_NO} from ${BACKUP_PART_CURRENT_SIZE}MiB to ${BACKUP_SIZE}MiB"
|
|
e2fsck -p -f ${instdev_part_prefix}${BACKUP_PART_NO}
|
|
rc=$?
|
|
# Handle e2fsck exit code, non-zero can still indicate success:
|
|
# 0 - No errors
|
|
# 1 - File system errors corrected
|
|
# 2 - File system errors corrected, system should be rebooted
|
|
# > 2 are all hard failures (see man e2fsck)
|
|
# Include 2 as a failure in our case, since it should only happen if the filesystem
|
|
# is mounted while e2fsck is run (not a valid scenario here).
|
|
[ ${rc} -gt 1 ] && report_failure_with_msg "e2fsck failed on platform backup partition [rc=${rc}]"
|
|
resize2fs -f ${instdev_part_prefix}${BACKUP_PART_NO}
|
|
rc=$?
|
|
[ ${rc} -ne 0 ] && report_failure_with_msg "Failed to resize ext4 fs of platform backup partition [rc=${rc}]"
|
|
fi
|
|
true
|
|
%end
|
|
|
|
###########################################################################
|
|
|
|
%mkfs --interpreter=/bin/bash
|
|
HOOK_LABEL="mkfs"
|
|
. /tmp/lat/ks_functions.sh
|
|
ilog "***************************************************"
|
|
ilog "*** Mkfs - Format Partitions & LVM Volumes ***"
|
|
ilog "***************************************************"
|
|
|
|
#######################################################
|
|
# From pre_disk_aio
|
|
######################################################
|
|
|
|
vg="volume group"
|
|
lv="logical volume"
|
|
dev=$(get_disk "${INSTDEV}")
|
|
dev_part_prefix=$(get_part_prefix "${dev}")
|
|
|
|
if [ "${controller}" = true ] ; then
|
|
if [ "${aio}" = true ] ; then
|
|
get_aio_controller_provisioning_sizes
|
|
else
|
|
get_std_controller_provisioning_sizes
|
|
fi
|
|
else
|
|
report_failure_with_msg "Unsupported install type: only Standard or All-in-one is supported"
|
|
fi
|
|
|
|
# Maintain BIOS partition mappings from previous releases
|
|
part_no=1
|
|
if [ "$USE_UEFI_PARTITIONS" = 0 -o "${controller}" = false ] ; then
|
|
# No formating for the BIOS boot partition
|
|
part_no=$((part_no+1))
|
|
fi
|
|
|
|
if [ "${controller}" = true ] ; then
|
|
ilog "BACKUP_SIZE : ${BACKUP_SIZE}"
|
|
ilog "BACKUP_PART_NO : ${BACKUP_PART_NO}"
|
|
ilog "BACKUP_PART_LABEL : ${BACKUP_PART_LABEL}"
|
|
ilog "BACKUP_PART_GUID : ${BACKUP_PART_GUID}"
|
|
ilog "BACKUP_PART : ${dev_part_prefix}${BACKUP_PART_NO}"
|
|
|
|
# Only init Platform Backup partition filesystem if the partition was just created
|
|
if [ ${BACKUP_PART_FOUND} -eq 0 ] ; then
|
|
ilog "Platform Backup Partition was CREATED. Initialize filesystem on ${dev_part_prefix}${BACKUP_PART_NO}"
|
|
mkfs.ext4 -F -L ${BACKUP_PART_LABEL} ${dev_part_prefix}${BACKUP_PART_NO}
|
|
[ ${?} -ne 0 ] && report_failure_with_msg "Failed Platform Backup partition filesystem init ${dev_part_prefix}${BACKUP_PART_NO}"
|
|
else
|
|
# Preserving the contents of the backup partition, but make sure it's labeled correctly
|
|
e2label ${dev_part_prefix}${BACKUP_PART_NO} ${BACKUP_PART_LABEL}
|
|
fi
|
|
part_no=$((part_no+1))
|
|
fi
|
|
|
|
# Maintain UEFI partition mappings from previous releases
|
|
mkfs.vfat -n otaefi ${dev_part_prefix}${part_no}
|
|
[ ${?} -ne 0 ] && report_failure_with_msg "Failed UEFI filesystem init: ${dev_part_prefix}${part_no}, rc=${?}"
|
|
part_no=$((part_no+1))
|
|
|
|
# Boot/Root OSTree Partition A (Note: OSTree Partition B not used)
|
|
if [ "${PART_SZ_BOOT}" != 0 ] ; then
|
|
mkfs.ext4 -F -L otaboot ${dev_part_prefix}${part_no}
|
|
[ ${?} -ne 0 ] && report_failure_with_msg "Failed Boot filesystem init: ${dev_part_prefix}${part_no}, rc=${?}"
|
|
part_no=$((part_no+1))
|
|
fi
|
|
|
|
if [ "${PART_SZ_ROOT}" != 0 ] ; then
|
|
mkfs.ext4 -F -L otaroot ${dev_part_prefix}${part_no}
|
|
[ ${?} -ne 0 ] && report_failure_with_msg "Failed Root filesystem init: ${dev_part_prefix}${part_no}, rc=${?}"
|
|
part_no=$((part_no+1))
|
|
fi
|
|
|
|
# Flux Partition
|
|
if [ "${LV_SZ_VAR}" = 0 -a "${INSTFLUX}" = 1 ] ; then
|
|
mkfs.ext4 -F -L fluxdata ${dev_part_prefix}${part_no}
|
|
[ ${?} -ne 0 ] && report_failure_with_msg "Failed Fluxdata (/var) filesystem init: ${dev_part_prefix}${part_no}, rc=${?}"
|
|
part_no=$((part_no+1))
|
|
fi
|
|
|
|
# Log important LVM config settings
|
|
log_lvm_conf "Installer Initial" /etc/lvm/lvm.conf
|
|
|
|
# Create Volume Group
|
|
pv_part=${dev_part_prefix}${part_no}
|
|
|
|
ilog "Install disk: ${INSTDEV}"
|
|
ilog "Current disk: ${dev} ; current partition index: $part_no"
|
|
ilog "LV_SZ_LOG (cgts--vg-log--lv size): ${LV_SZ_LOG} MB"
|
|
ilog "LV_SZ_ROOT (cgts--vg-root--lv) : ${LV_SZ_ROOT} MB"
|
|
ilog "LV_SZ_SCRATCH (cgts--vg-scratch--lv) : ${LV_SZ_SCRATCH} MB"
|
|
ilog "LV_SZ_VAR (cgts--vg-var--lv) : ${LV_SZ_VAR} MB"
|
|
|
|
ilog "Wipe any previous signatures from the platform physical volume ${pv_part}"
|
|
wipefs -a ${pv_part}
|
|
[ ${?} -ne 0 ] && report_failure_with_msg "Failed to wipe signatures from ${pv_part}, rc=${?}"
|
|
|
|
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}"
|
|
|
|
if [ "${LV_SZ_ROOT}" != 0 ] ; then
|
|
# Create and Init the '/' logical volume
|
|
ilog "Create ${lv} 'root-lv' ; $STOR_DEV_FDS"
|
|
exec_no_fds "$STOR_DEV_FDS" "lvcreate -y -Wy -Zy -n root-lv --size ${LV_SZ_ROOT}MB cgts-vg 2>/dev/null" 5 0.5
|
|
[ ${?} -ne 0 ] && report_failure_with_msg "Failed to create ${lv} 'root-lv'"
|
|
|
|
ilog "InitFs ${lv} 'root-lv'"
|
|
mkfs.ext4 -F /dev/cgts-vg/root-lv
|
|
[ ${?} -ne 0 ] && report_failure_with_msg "Failed to init ${lv} 'root-lv'"
|
|
fi
|
|
|
|
if [ "${LV_SZ_VAR}" != 0 ] ; then
|
|
# Create and Init the '/' logical volume
|
|
ilog "Create ${lv} 'var-lv' ; $STOR_DEV_FDS"
|
|
exec_no_fds "$STOR_DEV_FDS" "lvcreate -y -Wy -Zy -n var-lv --size ${LV_SZ_ROOT}MB cgts-vg 2>/dev/null" 5 0.5
|
|
[ ${?} -ne 0 ] && report_failure_with_msg "Failed to create ${lv} 'root-lv'"
|
|
|
|
ilog "InitFs ${lv} 'var-lv'"
|
|
mkfs.ext4 -F /dev/cgts-vg/var-lv
|
|
[ ${?} -ne 0 ] && report_failure_with_msg "Failed to init ${lv} 'root-lv'"
|
|
fi
|
|
|
|
# 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 ${LV_SZ_LOG}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 ${LV_SZ_SCRATCH}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
|
|
export LV_ROOTDISK=$(exec_no_fds "$STOR_DEV_FDS" "pvdisplay --select 'vg_name=cgts-vg' -C -o pv_name --noheadings" | xargs)
|
|
[ -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 "Installer Updated" /etc/lvm/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
|
|
|
|
# Stage the ostree_repo in /sysroot for network installations
|
|
# of controller nodes. Doing so avoids a double ostree pull of
|
|
# the huge ostree_repo over the network.
|
|
if is_usb_install -eq 0 ; then
|
|
|
|
ilog "USB Install"
|
|
|
|
else
|
|
|
|
ilog "Network Install"
|
|
|
|
##################################################################
|
|
#
|
|
# System node installs of worker and storage nodes are installed
|
|
# over the network rather than from a staged archive.
|
|
# This is because these node types do not have/need a local feed.
|
|
#
|
|
##################################################################
|
|
|
|
if [ "${controller}" = true ] ; then
|
|
|
|
ilog "Controller Install"
|
|
|
|
##############################################################
|
|
#
|
|
# Controller node network installs pull the ostree_repo from
|
|
# the pxeboot server's feed directory in 'archive' mode into
|
|
# /sysroot as a local staging location. In this case LAT's
|
|
# INSTL (install) variable is updated to install from that
|
|
# local stage.
|
|
#
|
|
# This is done to avoid a second (double) ostree_repo pull
|
|
# over the network that would otherwise be needed to populate
|
|
# the controller's feed directory.
|
|
#
|
|
# This staged ostree_repo archive is later moved to the
|
|
# controller's feed directory to be used for future installs
|
|
# of other system nodes from this controller.
|
|
#
|
|
##############################################################
|
|
|
|
ilog "OSTREE_ROOT_DEVICE: ${OSTREE_ROOT_DEVICE}"
|
|
ilog "OSTREE_VAR_DEVICE : ${OSTREE_VAR_DEVICE}"
|
|
|
|
PHYS_SYSROOT="/sysroot"
|
|
mkdir -p ${PHYS_SYSROOT}
|
|
mount -o rw,noatime "${OSTREE_ROOT_DEVICE}" "${PHYS_SYSROOT}" || elog "Error mounting ${OSTREE_ROOT_DEVICE}"
|
|
|
|
repo="${PHYS_SYSROOT}/var/www/pages/feed/rel-xxxPLATFORM_RELEASExxx/ostree_repo"
|
|
mkdir -p "${repo}"
|
|
|
|
# If we have already prestaged ostree_repo in /opt/platform-backup,
|
|
# then we should use that repo instead of downloading off of the system controller.
|
|
|
|
backup_device=/dev/disk/by-partlabel/platform_backup
|
|
backup_mount=/tmp/platform-backup
|
|
backup_mount_release="${backup_mount}"/xxxPLATFORM_RELEASExxx
|
|
|
|
ilog "Temporary backup mount: ${backup_mount}, release: ${backup_mount_release}"
|
|
mkdir -p "${backup_mount}"
|
|
mount "${backup_device}" "${backup_mount}" 2>/dev/null
|
|
|
|
# If ostree_repo is found at the mounted backup directory,
|
|
# then set the ostree url to its location.
|
|
remote_insturl=
|
|
if [ -e ${backup_mount_release}/ostree_repo ]; then
|
|
local_repo_check_fail=
|
|
# Calculate local checksum and compare
|
|
checksum_file=${backup_mount_release}/.ostree_repo_checksum
|
|
if [ -f "${checksum_file}" ]; then
|
|
checksum_from_file=$(cat "${checksum_file}")
|
|
ilog "Verifying checksum for prestaged ${backup_mount_release}/ostree_repo"
|
|
pushd ${backup_mount_release} > /dev/null
|
|
checksum=$(find ostree_repo -type f -exec md5sum {} + | LC_ALL=C sort | md5sum | awk '{ print $1; }')
|
|
popd > /dev/null
|
|
if [ "${checksum}" = "${checksum_from_file}" ]; then
|
|
ilog "Verified ostree checksum: ${checksum}"
|
|
else
|
|
elog "ostree checksum failed on ${backup_mount_release}/ostree_repo"
|
|
elog "Calulated checksum: ${checksum}"
|
|
elog "File checksum: ${checksum_from_file}"
|
|
local_repo_check_fail=true
|
|
fi
|
|
else
|
|
# No prestage checksum file is available. Use ostree fsck instead.
|
|
# The only problem with this is the length of time required for fsck to complete.
|
|
wlog "No ostree checksum file at ${checksum_file}. Performing ostree fsck instead."
|
|
if ! ostree --repo="${backup_mount_release}/ostree_repo" fsck; then
|
|
elog "ostree fsck failed on prestaged ${backup_mount_release}/ostree_repo: reverting to remote pull"
|
|
local_repo_check_fail=true
|
|
fi
|
|
fi
|
|
if [ -z "${local_repo_check_fail}" ]; then
|
|
# Preserve remote_insturl for use in 2nd ostree pull below
|
|
remote_insturl=${insturl}
|
|
|
|
insturl="file:///${backup_mount_release}/ostree_repo"
|
|
ilog "Setting insturl to ${insturl} to use prestaged ostree_repo"
|
|
else
|
|
# Remove the corrupted ostree_repo.
|
|
# Avoid setting insturl which will revert to using a remote pull
|
|
elog "ostree integrity check failed: removing prestaged ${backup_mount_release}/ostree_repo"
|
|
rm -rf "${backup_mount_release}/ostree_repo"
|
|
elog "ostree integrity check failed: reverting to remote pull"
|
|
fi
|
|
fi
|
|
|
|
# Tell LAT to install from this local stage
|
|
# i.e. override where LAT installs from.
|
|
export instl=${repo}
|
|
export INSTL=${instl}
|
|
|
|
ostree --repo=${repo} init --mode=archive
|
|
if [ "${insturl}" = "file://NOT_SET" ] ; then
|
|
ilog "ostree_repo archive pull from file:///instboot/ostree_repo"
|
|
ostree --repo=${repo} remote add ${instbr} file:///instboot/ostree_repo
|
|
else
|
|
ilog "ostree_repo archive pull from ${insturl}"
|
|
ostree --repo=${repo} remote add ${instbr} ${insturl}
|
|
fi
|
|
# Check for noverifyssl in boot arguments.
|
|
# Note: even if noverifyssl is not set, we still don't have proper support
|
|
# for SSL certificates (which would require configuring cert paths here).
|
|
if grep -q noverifyssl /proc/cmdline 2>/dev/null; then
|
|
ilog "Configuring ostree for unverified SSL"
|
|
ostree config --repo=${repo} set "remote \"${instbr}\"".tls-permissive true
|
|
fi
|
|
# Check for instgpg=0 in boot arguments.
|
|
if grep -q 'instgpg=0' /proc/cmdline 2>/dev/null; then
|
|
ilog "Configuring ostree for unverified GPG (gpg-verify=false)"
|
|
ostree config --repo=${repo} set "remote \"${instbr}\"".gpg-verify false
|
|
fi
|
|
|
|
ilog "Executing: ostree --repo=${repo} pull --depth=-1 --mirror ${instbr}:${instbr}"
|
|
MAX_TRIES=3
|
|
RETRY_WAIT=10
|
|
for try in 1 2 3
|
|
do
|
|
ostree --repo=${repo} pull --depth=-1 --mirror ${instbr}:${instbr}
|
|
rc=$?
|
|
if [ ${rc} -ne 0 ]; then
|
|
if [ ${try} -lt ${MAX_TRIES} ] ; then
|
|
wlog "ostree pull failed on try ${try} of ${MAX_TRIES}, rc=${rc} ; retry in ${RETRY_WAIT} seconds ..."
|
|
sleep ${RETRY_WAIT}
|
|
else
|
|
report_failure_with_msg "ostree pull failed, rc=${rc} ; max tries ${try} of ${MAX_TRIES}"
|
|
fi
|
|
else
|
|
break
|
|
fi
|
|
done
|
|
|
|
if [ -n "${remote_insturl}" ]; then
|
|
# In this case, we've initialized our ostree repo from local disk
|
|
# store - either via prestaging or due to installing from ISO.
|
|
# We now perform an extra ostree pull from the system controller
|
|
# in order to pick up any patch commits.
|
|
ilog "ostree_repo archive pull from ${remote_insturl} for patch commits"
|
|
|
|
# Set feed ostree remote "starlingx" to point to active controller's feed ostree repo
|
|
ilog "Replacing ostree feed remote with: ${remote_insturl} ${instbr}"
|
|
ostree --repo=${repo} remote delete ${instbr}
|
|
ostree --repo=${repo} remote add ${instbr} ${remote_insturl} ${instbr}
|
|
if grep -q noverifyssl /proc/cmdline 2>/dev/null; then
|
|
ilog "Configuring ostree for unverified SSL"
|
|
ostree config --repo=${repo} set "remote \"${instbr}\"".tls-permissive true
|
|
fi
|
|
if grep -q 'instgpg=0' /proc/cmdline 2>/dev/null; then
|
|
ilog "Configuring ostree for unverified GPG (gpg-verify=false)"
|
|
ostree config --repo=${repo} set "remote \"${instbr}\"".gpg-verify false
|
|
fi
|
|
ilog "Executing ostree pull from ${remote_insturl}:"
|
|
for try in 1 2 3
|
|
do
|
|
ostree --repo=${repo} pull --depth=-1 --mirror ${instbr}:${instbr}
|
|
rc=$?
|
|
if [ ${rc} -ne 0 ]; then
|
|
if [ ${try} -lt ${MAX_TRIES} ] ; then
|
|
wlog "ostree pull failed on try ${try} of ${MAX_TRIES}, rc=${rc} ; retry in ${RETRY_WAIT} seconds ..."
|
|
sleep ${RETRY_WAIT}
|
|
else
|
|
report_failure_with_msg "ostree pull failed, rc=${rc} ; max tries ${try} of ${MAX_TRIES}"
|
|
fi
|
|
else
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
ilog "ostree log for ${repo}, branch=${instbr}:"
|
|
ostree --repo=${repo} log ${instbr}
|
|
|
|
umount ${backup_mount}
|
|
umount ${PHYS_SYSROOT}
|
|
fi
|
|
fi
|
|
|
|
# Important: To align with installer expectations of where otaefi will reside,
|
|
# reset the value of p1
|
|
if [ "${controller}" = true ] ; then
|
|
if [ "$USE_UEFI_PARTITIONS" = 0 ] ; then
|
|
# BIOS firmware execution
|
|
# Number Start (sector) End (sector) Size Code Name
|
|
# 1 2048 4095 1024.0 KiB EF02 bios
|
|
# 2 4096 61444095 29.3 GiB FFFF platform_backup
|
|
# 3 61444096 62058495 300.0 MiB EF00 otaefi
|
|
#
|
|
p1=3
|
|
else
|
|
# UEFI firmware execution
|
|
# Number Start (sector) End (sector) Size Code Name
|
|
# 1 2048 61442047 29.3 GiB FFFF platform_backup
|
|
# 2 61442048 62056447 300.0 MiB EF00 otaefi
|
|
p1=2
|
|
|
|
# LAT installer will attempt to write the legacy BIOS grub information
|
|
# after exiting from this hook. Skip it, in this case, as we don't have
|
|
# a BIOS boot partition
|
|
export BIOSPLUSEFI=0
|
|
fi
|
|
elif [ "${worker}" = true -o "${storage}" = true ] ; then
|
|
# UEFI and BIOS firmware execution
|
|
# Number Start (sector) End (sector) Size Code Name
|
|
# 1 2048 4095 1024.0 KiB EF02 bios
|
|
# 2 4096 618495 300.0 MiB EF00 otaefi
|
|
p1=2
|
|
fi
|
|
|
|
# Important: Set fs_dev needed by the installer for mounting/updating the efi
|
|
# partition
|
|
fs_dev=${dev_part_prefix}
|
|
|
|
true
|
|
%end
|
|
|
|
###########################################################################
|
|
|
|
%post --interpreter=/bin/bash
|
|
HOOK_LABEL="post"
|
|
. /tmp/lat/ks_functions.sh
|
|
ilog "*********************************************************"
|
|
ilog "**** Post - Add user/groups **"
|
|
ilog "*********************************************************"
|
|
|
|
# Set password for root to 'root'
|
|
usermod -p '$6$hEv/K.fPeg/$ezIWhJPrMG3WtdEwqQRdyBwdYmPZkqW2PONFAcDd6TqWliYc9dHAwW4MFTlLanVH3/clE0/34FheDMpbAqZVG.' root
|
|
|
|
# Remove admin user whether it exists or not
|
|
deluser admin || true
|
|
|
|
# Create the sysadmin user
|
|
useradd sysadmin -m --shell /bin/bash -G sudo --password 4SuW8cnXFyxsk
|
|
chage -d 0 sysadmin
|
|
|
|
# add 'nobody' group
|
|
groupadd nobody
|
|
|
|
# Reload /etc/group- to make systemd-sysusers.service happy
|
|
/usr/sbin/grpconv || report_failure_with_msg "Failed to convert from shadow passwords and groups"
|
|
%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}"
|
|
if [ "${lowlatency}" = true ] ; then
|
|
ilog "Setting aio lowlatency"
|
|
ln -s /usr/share/systemd-presets/lowlatency.preset /etc/systemd/system-preset/10-aio.preset
|
|
else
|
|
ln -s /usr/share/systemd-presets/aio.preset /etc/systemd/system-preset/10-aio.preset
|
|
fi
|
|
else
|
|
ilog "${SYSTEM_TYPE__STANDARD} System"
|
|
system_type="${SYSTEM_TYPE__STANDARD}"
|
|
if [ "${worker}" = true ] ; then
|
|
subfunction=${SUBFUNCTION__WORKER}
|
|
if [ "${lowlatency}" = true ] ; then
|
|
ilog "Setting ${SUBFUNCTION__WORKER} lowlatency"
|
|
ln -s /usr/share/systemd-presets/worker-lowlatency.preset /etc/systemd/system-preset/10-${SUBFUNCTION__WORKER}.preset
|
|
else
|
|
ln -s /usr/share/systemd-presets/worker.preset /etc/systemd/system-preset/10-${SUBFUNCTION__WORKER}.preset
|
|
fi
|
|
elif [ "${storage}" = true ] ; then
|
|
subfunction=${SUBFUNCTION__STORAGE}
|
|
ilog "Setting ${SUBFUNCTION__STORAGE} preset"
|
|
ln -s /usr/share/systemd-presets/storage.preset /etc/systemd/system-preset/10-${SUBFUNCTION__STORAGE}.preset
|
|
else
|
|
subfunction=${SUBFUNCTION__CONTROLLER}
|
|
ilog "Setting ${SUBFUNCTION__CONTROLLER} preset"
|
|
ln -s /usr/share/systemd-presets/controller.preset /etc/systemd/system-preset/10-${SUBFUNCTION__CONTROLLER}.preset
|
|
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
|
|
|
|
ilog "Create systemd presets and set personality traits"
|
|
systemctl daemon-reload
|
|
systemctl --preset-mode=full preset-all
|
|
|
|
##############################################################
|
|
# 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}" == *"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
|
|
# We should never reach this code in miniboot:
|
|
report_failure_with_msg "Unexpected: 'storage' type not supported in miniboot"
|
|
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
|
|
|
|
if [ ! -z "${insthwsettle}" ]; then
|
|
if [[ ${insthwsettle} =~ ^[0-9]+$ ]]; then
|
|
add_kernel_option "hwsettle=${insthwsettle}"
|
|
fi
|
|
fi
|
|
|
|
if [ -n "${extra_boot_params}" ]; then
|
|
# Strip out any commas and replace with space.
|
|
extra_boot_params=${extra_boot_params//,/ } # replace all ',' with ' '
|
|
ilog "Adding extra_boot_params to kernel options: ${extra_boot_params}"
|
|
add_kernel_option "${extra_boot_params}"
|
|
fi
|
|
|
|
# Search the install kernel command line for the out-of-tree-drivers=
|
|
# option and if present propagate that to the disk boot kernel options.
|
|
CMDLINE=`cat /proc/cmdline`
|
|
param="out-of-tree-drivers"
|
|
for option in ${CMDLINE} ; do
|
|
opt=${option%%=*}
|
|
if [ "${param}" = "${opt}" ]; then
|
|
add_kernel_option "${option}"
|
|
break
|
|
fi
|
|
done
|
|
|
|
########################################################################################
|
|
|
|
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
|
|
|
|
ilog "Override LAT grub file"
|
|
GRUB_PATH_N_FILE="/boot/efi/EFI/BOOT/grub.cfg"
|
|
if [ ! -e ${GRUB_PATH_N_FILE}.lat ] ; then
|
|
mv ${GRUB_PATH_N_FILE} ${GRUB_PATH_N_FILE}.lat
|
|
cp /var/pxeboot/pxelinux.cfg.files/grub.cfg.stx ${GRUB_PATH_N_FILE}
|
|
fi
|
|
|
|
######################################################################
|
|
# From post_system_aio
|
|
######################################################################
|
|
TEMPLATE_FILE="/usr/share/worker-utils/config/worker_reserved.conf"
|
|
TARGET_FILE="/etc/platform/worker_reserved.conf"
|
|
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
|
|
|
|
# Normally we would set personality based files later
|
|
# But we need to copy worker_reserved.conf now since it needs to be modified for AIO
|
|
ilog "${SYSTEM_TYPE__AIO} Reserved Memory: ${RESERVEDMEM}"
|
|
if [ ! -e "${TEMPLATE_FILE}" ] ; then
|
|
report_failure_with_msg "Cannot configure worker cpu/memory ; missing ${TEMPLATE_FILE}"
|
|
fi
|
|
cp "${TEMPLATE_FILE}" "${TARGET_FILE}"
|
|
if [ ! -e "${TARGET_FILE}" ] ; then
|
|
report_failure_with_msg "Cannot configure worker cpu/memory ; missing ${TARGET_FILE}"
|
|
fi
|
|
sed -i -e "s#\(WORKER_BASE_RESERVED\)=.*#\1=(\"node0:${RESERVEDMEM}MB:1\" \"node1:2000MB:0\" \"node2:2000MB:0\" \"node3:2000MB:0\")#g" "${TARGET_FILE}"
|
|
if [ $? -ne 0 ] ; then
|
|
report_failure_with_msg "Cannot configure worker cpu/memory ; previous sed search and replace request failed"
|
|
fi
|
|
worker_reserved=$(grep WORKER_BASE_RESERVED "${TARGET_FILE}")
|
|
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))\"/" "${TARGET_FILE}"
|
|
|
|
worker_cpu_list=$(grep WORKER_CPU_LIST "${TARGET_FILE}")
|
|
ilog "${SYSTEM_TYPE__AIO} '${worker_cpu_list}'"
|
|
elif [ "${worker}" = true ] ; then
|
|
# Keep logic contained and copy worker_reserved.conf now since we need
|
|
# to do the copy for AIO above
|
|
ilog "Enable ${TARGET_FILE} for ${TRAIT__WORKER}"
|
|
if [ ! -e "${TEMPLATE_FILE}" ] ; then
|
|
report_failure_with_msg "Cannot configure worker cpu/memory ; missing ${TEMPLATE_FILE}"
|
|
fi
|
|
cp "${TEMPLATE_FILE}" "${TARGET_FILE}"
|
|
if [ ! -e "${TARGET_FILE}" ] ; then
|
|
report_failure_with_msg "Cannot configure worker cpu/memory ; missing ${TARGET_FILE}"
|
|
fi
|
|
fi
|
|
|
|
true
|
|
%end
|
|
|
|
###########################################################################
|
|
|
|
%post --interpreter=/bin/bash --nochroot
|
|
HOOK_LABEL="post_nochroot"
|
|
. /tmp/lat/ks_functions.sh
|
|
|
|
ilog "************************************"
|
|
ilog "*** Post - Interface Setup ***"
|
|
ilog "************************************"
|
|
|
|
ilog "Creating network definitions in /etc/network/interfaces.d"
|
|
parse_miniboot_network_params
|
|
|
|
mgmt_dev=${BOOTPARAM_IFNAME}
|
|
mgmt_vlan=${BOOTPARAM_VLAN}
|
|
mgmt_address_family=${BOOTPARAM_MGMT_ADDRESS_FAMILY}
|
|
|
|
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"
|
|
|
|
function create_network_interface_file()
|
|
{
|
|
local ifname=${1}
|
|
local address_family=${2}
|
|
local vlan=${3:-}
|
|
|
|
local ipversion=ipv4
|
|
local ip_cmd_flag="-4"
|
|
if [ "${address_family}" == "inet6" ]; then
|
|
local ipversion=ipv6
|
|
local ip_cmd_flag="-6"
|
|
fi
|
|
local ifname_vlan="vlan${vlan}"
|
|
|
|
local logstr="Creating ${IMAGE_ROOTFS}/etc/network/interfaces.d/ifcfg-${ifname}, ${ipversion}"
|
|
[ -n "${vlan}" ] && logstr="${logstr}, vlan interface: ${ifname_vlan}"
|
|
[ -n "${BOOTPARAM_GW}" ] && logstr="${logstr}, gw: ${BOOTPARAM_GW}"
|
|
ilog "${logstr}"
|
|
|
|
local output
|
|
if [ -z "${vlan}" ]; then
|
|
# Persist the boot device to the platform configuration
|
|
# overwritten later if the management_interface is on a bonded interface.
|
|
update_platform_conf "management_interface=${ifname}"
|
|
|
|
# NO VLAN
|
|
output="auto ${ifname}\n"
|
|
output="${output}iface ${ifname} ${address_family} static\n"
|
|
output="${output} address ${BOOTPARAM_IP_ADDR}/$BOOTPARAM_PREFIX_LEN\n"
|
|
if [ -n "${BOOTPARAM_GW}" ]; then
|
|
output="${output} gateway $BOOTPARAM_GW\n"
|
|
fi
|
|
output="${output} mtu 1500\n"
|
|
output="${output} post-up echo 0 > /proc/sys/net/ipv6/conf/${ifname}/autoconf\n"
|
|
output="${output} post-up echo 0 > /proc/sys/net/ipv6/conf/${ifname}/accept_ra\n"
|
|
output="${output} post-up echo 0 > /proc/sys/net/ipv6/conf/${ifname}/accept_redirects\n"
|
|
echo -e "${output}" > "${IMAGE_ROOTFS}/etc/network/interfaces.d/ifcfg-${ifname}"
|
|
else
|
|
# CONFIGURE FOR VLAN
|
|
# 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=${ifname_vlan}"
|
|
|
|
# 1. Configure device interface:
|
|
output="auto ${ifname}\n"
|
|
output="${output}iface ${ifname} ${address_family} manual\n"
|
|
output="${output} post-up echo 0 > /proc/sys/net/ipv6/conf/${ifname}/autoconf\n"
|
|
output="${output} post-up echo 0 > /proc/sys/net/ipv6/conf/${ifname}/accept_ra\n"
|
|
output="${output} post-up echo 0 > /proc/sys/net/ipv6/conf/${ifname}/accept_redirects\n"
|
|
echo -e "${output}" > "${IMAGE_ROOTFS}/etc/network/interfaces.d/ifcfg-${ifname}"
|
|
|
|
# 2. Configure VLAN interface:
|
|
output="auto ${ifname_vlan}\n"
|
|
output="${output}iface ${ifname_vlan} ${address_family} static\n"
|
|
output="${output} vlan-raw-device ${ifname}\n"
|
|
output="${output} address ${BOOTPARAM_IP_ADDR}/${BOOTPARAM_PREFIX_LEN}\n"
|
|
if [ -n "${BOOTPARAM_GW}" ]; then
|
|
output="${output} gateway ${BOOTPARAM_GW}\n"
|
|
fi
|
|
output="${output} mtu 1500\n"
|
|
output="${output} post-up echo 0 > /proc/sys/net/ipv6/conf/${ifname_vlan}/autoconf\n"
|
|
output="${output} post-up echo 0 > /proc/sys/net/ipv6/conf/${ifname_vlan}/accept_ra\n"
|
|
output="${output} post-up echo 0 > /proc/sys/net/ipv6/conf/${ifname_vlan}/accept_redirects\n"
|
|
echo -e "${output}" > "${IMAGE_ROOTFS}/etc/network/interfaces.d/ifcfg-${ifname_vlan}"
|
|
fi
|
|
}
|
|
|
|
# Build networking scripts
|
|
|
|
# Loopback file
|
|
lo_file="${IMAGE_ROOTFS}/etc/network/interfaces.d/ifcfg-lo"
|
|
echo "auto lo" > "${lo_file}"
|
|
echo "iface lo ${mgmt_address_family} loopback" >> "${lo_file}"
|
|
|
|
if [ "${mgmt_dev}" != "lo" ]; then
|
|
create_network_interface_file "${mgmt_dev}" "${mgmt_address_family}" "${mgmt_vlan}"
|
|
fi
|
|
|
|
ilog "Contents of ${IMAGE_ROOTFS}/etc/network/interfaces.d/ifcfg-lo:"
|
|
ilog "$(cat "${IMAGE_ROOTFS}/etc/network/interfaces.d/ifcfg-lo")"
|
|
|
|
ilog "Contents of ${IMAGE_ROOTFS}/etc/network/interfaces.d/ifcfg-${mgmt_dev}:"
|
|
ilog "$(cat "${IMAGE_ROOTFS}/etc/network/interfaces.d/ifcfg-${mgmt_dev}")"
|
|
|
|
if [ -f "${IMAGE_ROOTFS}/etc/network/interfaces.d/ifcfg-vlan${mgmt_vlan}" ]; then
|
|
ilog "Contents of ${IMAGE_ROOTFS}/etc/network/interfaces.d/ifcfg-vlan${mgmt_vlan}:"
|
|
ilog "$(cat "${IMAGE_ROOTFS}/etc/network/interfaces.d/ifcfg-vlan${mgmt_vlan}")"
|
|
fi
|
|
|
|
# Clean machine-id file, it needs to be generated after install.
|
|
# It must be unique per installation because it is used to generate
|
|
# random MACs for SR-IOV VFs, among other resources.
|
|
find / -name machine-id | xargs rm -fv
|
|
|
|
true
|
|
%end
|
|
|
|
##########################################################################
|
|
|
|
%post --interpreter=/bin/bash --nochroot
|
|
HOOK_LABEL="post_nochroot"
|
|
. /tmp/lat/ks_functions.sh
|
|
ilog "*********************************************************"
|
|
ilog "*** Post Nochroot - 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
|
|
# miniboot: this code should never be hit
|
|
report_failure_with_msg "Unexpected: incorrect node during UUID creation"
|
|
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 - Restage OSTree repo ***"
|
|
ilog "*** - 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" # updated by the build
|
|
|
|
feed="${IMAGE_ROOTFS}/var/www/pages/feed/rel-${sw_release}"
|
|
repo="${feed}/ostree_repo"
|
|
pxedir="${IMAGE_ROOTFS}/var/pxeboot"
|
|
|
|
if [ ${OSTREE_REPO_FETCHED} -eq 0 ] ; then
|
|
if is_usb_install -eq 0 ; then
|
|
# miniboot: always false
|
|
report_failure_with_msg "Unexpected miniboot code block: usb install"
|
|
else
|
|
ilog "Stage ostree_repo from previous /sysroot pull to ${repo}"
|
|
mv -f /sysroot/var/www/pages/feed/rel-${sw_release}/ostree_repo ${IMAGE_ROOTFS}/var/www/pages/feed/rel-${sw_release}/
|
|
fi
|
|
|
|
# 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}
|
|
# Set feed ostree remote "starlingx" to point to active controller's feed ostree repo
|
|
feed_remote_name="starlingx"
|
|
feed_remote_url="http://controller:8080/feed/rel-${sw_release}/ostree_repo/"
|
|
ilog "Replacing ostree feed remote with: ${feed_remote_url} ${feed_remote_name}"
|
|
ostree --repo=${repo} remote delete ${feed_remote_name}
|
|
ostree --repo=${repo} remote add ${feed_remote_name} ${feed_remote_url} ${feed_branch}
|
|
|
|
# This fetch is only needed once because the repo is stored in /var
|
|
set_variable "ostree_repo_fetched"
|
|
|
|
# If the miniboot ISO contains a patches directory
|
|
if [ -d "/instboot/patches" ]; then
|
|
ilog "Prepatched iso"
|
|
ilog "Creating USM metadata directories"
|
|
mkdir -p ${IMAGE_ROOTFS}/var/rootdirs/opt/software/metadata/{committed,available,deployed}
|
|
cp -a /instboot/patches/* ${IMAGE_ROOTFS}/var/rootdirs/opt/software/metadata/deployed/
|
|
fi
|
|
|
|
# copy efi.img to /var/pxeboot to enable duplex/multinode subclouds
|
|
cp -a /instboot/efi.img ${pxedir}
|
|
rc=$?
|
|
if [ ${rc} -ne 0 ]; then
|
|
elog "Failed to copy efi.img to ${pxedir}"
|
|
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.
|
|
if [ ! -e ${pxedir}/EFI/BOOT ]; then
|
|
mkdir -p ${pxedir}/EFI/BOOT
|
|
fi
|
|
|
|
pushd ${pxedir}/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
|
|
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
|
|
cp /lat-installer* ${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
|
|
[ -f ${IMAGE_ROOTFS}/var/lib/dpkg/triggers/Unincorp ] && 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 filesystem access ***"
|
|
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/rootdirs/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
|
|
|
|
# Report and update the lvm config for the sysroot. Remove preceeding tab and
|
|
# convert to spaces to align with puppet expectations
|
|
LV_PERSISTENT_ROOTDISK=$(get_persistent_disk ${LV_ROOTDISK})
|
|
log_lvm_conf "SysRoot Initial" ${IMAGE_ROOTFS}/etc/lvm/lvm.conf
|
|
ilog ""
|
|
ilog "Update the LVM global filter to enable the initial physical volume only: ${LV_PERSISTENT_ROOTDISK}"
|
|
ilog ""
|
|
sed -i "s@^\(\s*\)# global_filter = \[.*@ global_filter = [ \"a|${LV_PERSISTENT_ROOTDISK}|\", \"r|.*|\" ]@" ${IMAGE_ROOTFS}/etc/lvm/lvm.conf
|
|
log_lvm_conf "SysRoot Updated" ${IMAGE_ROOTFS}/etc/lvm/lvm.conf
|
|
|
|
eject_device=$(eject -d | awk -F\` '{print $2}' | awk -F\' '{print $1}')
|
|
ilog "eject device=$eject_device"
|
|
eject $eject_device
|
|
rc=$?
|
|
[ $rc -ne 0 ] && elog "eject failed, rc=$rc"
|
|
|
|
# Create first_boot flag
|
|
touch ${IMAGE_ROOTFS}/etc/platform/.first_boot
|
|
# Create first controller flag
|
|
touch ${IMAGE_ROOTFS}/etc/platform/.first_controller
|
|
|
|
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 package links per node type ***"
|
|
ilog "****************************************************************"
|
|
ilog "IMAGE_ROOTFS=${IMAGE_ROOTFS}"
|
|
|
|
if [ ! -d "${IMAGE_ROOTFS}/etc/goenabled.d" ]; then
|
|
wlog "Directory ${IMAGE_ROOTFS}/etc/goenabled.d is missing, creating it now"
|
|
mkdir ${IMAGE_ROOTFS}/etc/goenabled.d
|
|
fi
|
|
|
|
if [ ! "${controller}" = true -a "${worker}" = true ] ; then
|
|
ilog "Setting up ${TRAIT__WORKER} package file links"
|
|
ln -s /etc/goenabled.d/config_goenabled_check.sh.worker ${IMAGE_ROOTFS}/etc/goenabled.d/config_goenabled_check.sh
|
|
ln -s /dev/null ${IMAGE_ROOTFS}/etc/systemd/system/controllerconfig.service
|
|
ln -s /dev/null ${IMAGE_ROOTFS}/etc/systemd/system/storageconfig.service
|
|
elif [ "${storage}" = true ] ; then
|
|
ilog "Setting up ${TRAIT__STORAGE} package file links"
|
|
ln -s /etc/goenabled.d/config_goenabled_check.sh.storage ${IMAGE_ROOTFS}/etc/goenabled.d/config_goenabled_check.sh
|
|
ln -s /dev/null ${IMAGE_ROOTFS}/etc/systemd/system/controllerconfig.service
|
|
ln -s /dev/null ${IMAGE_ROOTFS}/etc/systemd/system/workerconfig.service
|
|
elif [ "${controller}" = true ] ; then
|
|
ilog "Setting up ${TRAIT__CONTROLLER} package file links"
|
|
ln -s /etc/goenabled.d/config_goenabled_check.sh.controller ${IMAGE_ROOTFS}/etc/goenabled.d/config_goenabled_check.sh
|
|
ln -s /dev/null ${IMAGE_ROOTFS}/etc/systemd/system/workerconfig.service
|
|
ln -s /dev/null ${IMAGE_ROOTFS}/etc/systemd/system/storageconfig.service
|
|
fi
|
|
|
|
chmod 700 ${IMAGE_ROOTFS}/etc/goenabled.d/config_goenabled_check.sh
|
|
|
|
if [[ ! -d "${IMAGE_ROOTFS}/etc/pmon.d" ]]; then
|
|
wlog "Directory ${IMAGE_ROOTFS}/etc/pmon.d/ is missing, creating it now"
|
|
mkdir ${IMAGE_ROOTFS}/etc/pmon.d
|
|
fi
|
|
|
|
if [ "${controller}" = true ] ; then
|
|
ilog "Setting up pmon files for ${TRAIT__CONTROLLER} and/or ${TRAIT__CONTROLLER} side of ${SYSTEM_TYPE__AIO}"
|
|
ln -s /usr/share/starlingx/pmon.d/acpid.conf ${IMAGE_ROOTFS}/etc/pmon.d/acpid.conf
|
|
ln -s /usr/share/starlingx/pmon.d/containerd.conf ${IMAGE_ROOTFS}/etc/pmon.d/containerd.conf
|
|
ln -s /usr/share/starlingx/pmon.d/docker.conf ${IMAGE_ROOTFS}/etc/pmon.d/docker.conf
|
|
ln -s /usr/share/starlingx/pmon.d/fm-api.conf ${IMAGE_ROOTFS}/etc/pmon.d/fm-api.conf
|
|
ln -s /usr/share/starlingx/pmon.d/fsmon.conf ${IMAGE_ROOTFS}/etc/pmon.d/fsmon.conf
|
|
ln -s /usr/share/starlingx/pmon.d/hbsAgent.conf ${IMAGE_ROOTFS}/etc/pmon.d/hbsAgent.conf
|
|
ln -s /usr/share/starlingx/pmon.d/hbsClient.conf ${IMAGE_ROOTFS}/etc/pmon.d/hbsClient.conf
|
|
ln -s /usr/share/starlingx/pmon.d/lmon.conf ${IMAGE_ROOTFS}/etc/pmon.d/lmon.conf
|
|
ln -s /usr/share/starlingx/pmon.d/logmgmt ${IMAGE_ROOTFS}/etc/pmon.d/logmgmt
|
|
ln -s /usr/share/starlingx/pmon.d/mtcClient.conf ${IMAGE_ROOTFS}/etc/pmon.d/mtcClient.conf
|
|
ln -s /usr/share/starlingx/pmon.d/mtcalarm.conf ${IMAGE_ROOTFS}/etc/pmon.d/mtcalarm.conf
|
|
ln -s /usr/share/starlingx/pmon.d/mtclogd.conf ${IMAGE_ROOTFS}/etc/pmon.d/mtclogd.conf
|
|
ln -s /usr/share/starlingx/pmon.d/sm-api.conf ${IMAGE_ROOTFS}/etc/pmon.d/sm-api.conf
|
|
ln -s /usr/share/starlingx/pmon.d/sm-eru.conf ${IMAGE_ROOTFS}/etc/pmon.d/sm-eru.conf
|
|
ln -s /usr/share/starlingx/pmon.d/sm.conf ${IMAGE_ROOTFS}/etc/pmon.d/sm.conf
|
|
ln -s /usr/share/starlingx/pmon.d/sshd.conf ${IMAGE_ROOTFS}/etc/pmon.d/sshd.conf
|
|
ln -s /usr/share/starlingx/pmon.d/sssd.conf ${IMAGE_ROOTFS}/etc/pmon.d/sssd.conf
|
|
ln -s /usr/share/starlingx/pmon.d/sw-patch-agent.conf ${IMAGE_ROOTFS}/etc/pmon.d/sw-patch-agent.conf
|
|
ln -s /usr/share/starlingx/pmon.d/sw-patch-controller-daemon.conf ${IMAGE_ROOTFS}/etc/pmon.d/sw-patch-controller-daemon.conf
|
|
ln -s /usr/share/starlingx/pmon.d/sysinv-agent.conf ${IMAGE_ROOTFS}/etc/pmon.d/sysinv-agent.conf
|
|
ln -s /usr/share/starlingx/pmon.d/syslog-ng.conf ${IMAGE_ROOTFS}/etc/pmon.d/syslog-ng.conf
|
|
ln -s /usr/share/starlingx/pmon.d/luks.conf ${IMAGE_ROOTFS}/etc/pmon.d/luks.conf
|
|
ln -s /usr/share/starlingx/pmon.d/ipsec-server.conf ${IMAGE_ROOTFS}/etc/pmon.d/ipsec-server.conf
|
|
ln -s /usr/share/starlingx/pmon.d/software-controller-daemon.conf ${IMAGE_ROOTFS}/etc/pmon.d/software-controller-daemon.conf
|
|
ln -s /usr/share/starlingx/pmon.d/software-agent.conf ${IMAGE_ROOTFS}/etc/pmon.d/software-agent.conf
|
|
fi
|
|
if [ "${worker}" = true ] ; then
|
|
ilog "Setting up pmon files for ${TRAIT__WORKER} and/or ${TRAIT__WORKER} side of ${SYSTEM_TYPE__AIO}"
|
|
ln -s /usr/share/starlingx/pmon.d/acpid.conf ${IMAGE_ROOTFS}/etc/pmon.d/acpid.conf
|
|
ln -s /usr/share/starlingx/pmon.d/containerd.conf ${IMAGE_ROOTFS}/etc/pmon.d/containerd.conf
|
|
ln -s /usr/share/starlingx/pmon.d/docker.conf ${IMAGE_ROOTFS}/etc/pmon.d/docker.conf
|
|
ln -s /usr/share/starlingx/pmon.d/fsmon.conf ${IMAGE_ROOTFS}/etc/pmon.d/fsmon.conf
|
|
ln -s /usr/share/starlingx/pmon.d/hbsClient.conf ${IMAGE_ROOTFS}/etc/pmon.d/hbsClient.conf
|
|
ln -s /usr/share/starlingx/pmon.d/isolcpu_plugin.conf ${IMAGE_ROOTFS}/etc/pmon.d/isolcpu_plugin.conf
|
|
ln -s /usr/share/starlingx/pmon.d/lmon.conf ${IMAGE_ROOTFS}/etc/pmon.d/lmon.conf
|
|
ln -s /usr/share/starlingx/pmon.d/logmgmt ${IMAGE_ROOTFS}/etc/pmon.d/logmgmt
|
|
ln -s /usr/share/starlingx/pmon.d/mtcClient.conf ${IMAGE_ROOTFS}/etc/pmon.d/mtcClient.conf
|
|
ln -s /usr/share/starlingx/pmon.d/mtcalarm.conf ${IMAGE_ROOTFS}/etc/pmon.d/mtcalarm.conf
|
|
ln -s /usr/share/starlingx/pmon.d/mtclogd.conf ${IMAGE_ROOTFS}/etc/pmon.d/mtclogd.conf
|
|
ln -s /usr/share/starlingx/pmon.d/sm-eru.conf ${IMAGE_ROOTFS}/etc/pmon.d/sm-eru.conf
|
|
ln -s /usr/share/starlingx/pmon.d/sshd.conf ${IMAGE_ROOTFS}/etc/pmon.d/sshd.conf
|
|
ln -s /usr/share/starlingx/pmon.d/sssd.conf ${IMAGE_ROOTFS}/etc/pmon.d/sssd.conf
|
|
ln -s /usr/share/starlingx/pmon.d/sw-patch-agent.conf ${IMAGE_ROOTFS}/etc/pmon.d/sw-patch-agent.conf
|
|
ln -s /usr/share/starlingx/pmon.d/sysinv-agent.conf ${IMAGE_ROOTFS}/etc/pmon.d/sysinv-agent.conf
|
|
ln -s /usr/share/starlingx/pmon.d/syslog-ng.conf ${IMAGE_ROOTFS}/etc/pmon.d/syslog-ng.conf
|
|
ln -s /usr/share/starlingx/pmon.d/software-agent.conf ${IMAGE_ROOTFS}/etc/pmon.d/software-agent.conf
|
|
fi
|
|
if [ "${storage}" = true ] ; then
|
|
ilog "Setting up pmon files for ${TRAIT__STORAGE} and/or ${TRAIT__STORAGE} side of ${SYSTEM_TYPE__AIO}"
|
|
ln -s /usr/share/starlingx/pmon.d/acpid.conf ${IMAGE_ROOTFS}/etc/pmon.d/acpid.conf
|
|
ln -s /usr/share/starlingx/pmon.d/containerd.conf ${IMAGE_ROOTFS}/etc/pmon.d/containerd.conf
|
|
ln -s /usr/share/starlingx/pmon.d/docker.conf ${IMAGE_ROOTFS}/etc/pmon.d/docker.conf
|
|
ln -s /usr/share/starlingx/pmon.d/fsmon.conf ${IMAGE_ROOTFS}/etc/pmon.d/fsmon.conf
|
|
ln -s /usr/share/starlingx/pmon.d/hbsClient.conf ${IMAGE_ROOTFS}/etc/pmon.d/hbsClient.conf
|
|
ln -s /usr/share/starlingx/pmon.d/lmon.conf ${IMAGE_ROOTFS}/etc/pmon.d/lmon.conf
|
|
ln -s /usr/share/starlingx/pmon.d/logmgmt ${IMAGE_ROOTFS}/etc/pmon.d/logmgmt
|
|
ln -s /usr/share/starlingx/pmon.d/mtcClient.conf ${IMAGE_ROOTFS}/etc/pmon.d/mtcClient.conf
|
|
ln -s /usr/share/starlingx/pmon.d/mtcalarm.conf ${IMAGE_ROOTFS}/etc/pmon.d/mtcalarm.conf
|
|
ln -s /usr/share/starlingx/pmon.d/mtclogd.conf ${IMAGE_ROOTFS}/etc/pmon.d/mtclogd.conf
|
|
ln -s /usr/share/starlingx/pmon.d/sm-eru.conf ${IMAGE_ROOTFS}/etc/pmon.d/sm-eru.conf
|
|
ln -s /usr/share/starlingx/pmon.d/sshd.conf ${IMAGE_ROOTFS}/etc/pmon.d/sshd.conf
|
|
ln -s /usr/share/starlingx/pmon.d/sssd.conf ${IMAGE_ROOTFS}/etc/pmon.d/sssd.conf
|
|
ln -s /usr/share/starlingx/pmon.d/sw-patch-agent.conf ${IMAGE_ROOTFS}/etc/pmon.d/sw-patch-agent.conf
|
|
ln -s /usr/share/starlingx/pmon.d/sysinv-agent.conf ${IMAGE_ROOTFS}/etc/pmon.d/sysinv-agent.conf
|
|
ln -s /usr/share/starlingx/pmon.d/syslog-ng.conf ${IMAGE_ROOTFS}/etc/pmon.d/syslog-ng.conf
|
|
ln -s /usr/share/starlingx/pmon.d/software-agent.conf ${IMAGE_ROOTFS}/etc/pmon.d/software-agent.conf
|
|
fi
|
|
|
|
true
|
|
# Warning: Do not remove the line feed from the end of this file
|
|
# or the install will fail with a permission denied error.
|
|
%end
|
|
|
|
# vim: filetype=sh
|