# # Copyright (c) 2023 Wind River Systems, Inc. # SPDX-License-Identifier: Apache-2.0 # %pre # This file defines functions that can be used in %pre and %post kickstart sections, by including: # . /tmp/ks-functions.sh # cat </tmp/ks-functions.sh # # Copyright (c) 2023 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # function wlog() { [ -z "\$stdout" ] && stdout=1 local dt="\$(date "+%Y-%m-%d %H:%M:%S.%3N")" echo "\$dt - \$1" >&\${stdout} } function get_by_path() { local dev_name=\$(basename \$1) if echo "\$dev_name" | grep -q mpath; then exec_retry 30 1 "ls /dev/mapper/\$dev_name" > /dev/null fi for p in /dev/mapper/mpath*; do if [ "\$p" = "\$1" -o "\$p" = "/dev/mapper/\$dev_name" ]; then find -L /dev/disk/by-id/dm-uuid* -samefile /dev/mapper/\$dev_name return fi done local disk=\$(cd /dev ; readlink -f \$1) for p in /dev/disk/by-path/*; do if [ "\$disk" = "\$(readlink -f \$p)" ]; then echo \$p return fi done } function get_disk() { if echo \$1 | grep -q mpath; then find -L /dev/mapper/ -samefile \$1 return fi echo \$(cd /dev ; readlink -f \$1) } function report_pre_failure_with_msg() { local msg=\$1 echo -e '\n\nInstallation failed.\n' echo "\$msg" exit 1 } function report_prestaging_failure_with_msg() { local msg=\$1 echo -e '\n\nPrestaging failed.\n' echo "\$msg" exit 1 } function report_post_failure_with_msg() { local msg=\$1 cat <> /etc/motd Installation failed. \$msg EOF if [ -d /etc/platform ] ; then echo "\$msg" >/etc/platform/installation_failed fi echo -e '\n\nInstallation failed.\n' echo "\$msg" exit 1 } function report_post_failure_with_logfile() { local logfile=\$1 cat <> /etc/motd Installation failed. Please see \$logfile for details of failure EOF if [ -d /etc/platform ] ; then echo \$logfile >/etc/platform/installation_failed fi echo -e '\n\nInstallation failed.\n' cat \$logfile exit 1 } function get_http_port() { echo \$(cat /proc/cmdline |xargs -n1 echo |grep '^inst.repo=' | sed -r 's#^[^/]*://[^/]*:([0-9]*)/.*#\1#') } function get_disk_dev() { local disk # Detect HDD for blk_dev in vda vdb sda sdb dda ddb hda hdb; do if [ -d /sys/block/\$blk_dev ]; then disk=\$(ls -l /sys/block/\$blk_dev | grep -v usb | head -n1 | sed 's/^.*\([vsdh]d[a-z]\+\).*$/\1/'); if [ -n "\$disk" ]; then exec_retry 3 0.5 "multipath -c /dev/\$disk" > /dev/null && continue echo "\$disk" return fi fi done for blk_dev in nvme0n1 nvme1n1; do if [ -d /sys/block/\$blk_dev ]; then disk=\$(ls -l /sys/block/\$blk_dev | grep -v usb | head -n1 | sed 's/^.*\(nvme[01]n1\).*$/\1/'); if [ -n "\$disk" ]; then echo "\$disk" return fi fi done for mpath_dev in mpatha mpathb; do if [ -e /dev/mapper/\$mpath_dev ]; then echo "/dev/mapper/\$mpath_dev" return fi done } 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 } function exec_retry() { local retries=\$1 local interval=\$2 local cmd=\$3 let -i retry_count=1 local ret_code=0 local ret_stdout="" cmd="\$cmd" # 2>&\$stdout" while [ \$retry_count -le \$retries ]; do #wlog "Running command: '\$cmd'." ret_stdout=\$(eval \$cmd) ret_code=\$? [ \$ret_code -eq 0 ] && break wlog "Error running command '\${cmd}'. Try \${retry_count} of \${retries} at \${interval}s." wlog "ret_code: \${ret_code}, stdout: '\${ret_stdout}'." sleep \$interval let retry_count++ done echo "\${ret_stdout}" return \${ret_code} } # This is a developer debug tool that can be line inserted in any kickstart. # Code should not be committed with a call to this function. # When inserted and hit, execution will stall until one of the 2 conditions: # 1. /tmp/wait_for_go file is removed 'manually' # 2. or after 10 minutes function wait_for_go() { touch /tmp/wait_for_go for loop in {1..60} ; do sleep 10 if [ ! -e "/tmp/wait_for_go" ] ; then break fi done } END_FUNCTIONS %end %post # This file defines functions that can be used in %pre and %post kickstart sections, by including: # . /tmp/ks-functions.sh # cat </tmp/ks-functions.sh # # Copyright (c) 2023 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # function wlog() { [ -z "\$stdout" ] && stdout=1 local dt="\$(date "+%Y-%m-%d %H:%M:%S.%3N")" echo "\$dt - \$1" >&\${stdout} } function get_by_path() { local dev_name=\$(basename \$1) if echo "\$dev_name" | grep -q mpath; then exec_retry 30 1 "ls /dev/mapper/\$dev_name" > /dev/null fi for p in /dev/mapper/mpath*; do if [ "\$p" = "\$1" -o "\$p" = "/dev/mapper/\$dev_name" ]; then find -L /dev/disk/by-id/dm-uuid* -samefile /dev/mapper/\$dev_name return fi done local disk=\$(cd /dev ; readlink -f \$1) for p in /dev/disk/by-path/*; do if [ "\$disk" = "\$(readlink -f \$p)" ]; then echo \$p return fi done } function get_disk() { if echo \$1 | grep -q mpath; then find -L /dev/mapper/ -samefile \$1 return fi echo \$(cd /dev ; readlink -f \$1) } function report_pre_failure_with_msg() { local msg=\$1 echo -e '\n\nInstallation failed.\n' echo "\$msg" exit 1 } function report_prestaging_failure_with_msg() { local msg=\$1 echo -e '\n\nPrestaging failed.\n' echo "\$msg" exit 1 } function report_post_failure_with_msg() { local msg=\$1 cat <> /etc/motd Installation failed. \$msg EOF if [ -d /etc/platform ] ; then echo "\$msg" >/etc/platform/installation_failed fi echo -e '\n\nInstallation failed.\n' echo "\$msg" exit 1 } function report_post_failure_with_logfile() { local logfile=\$1 cat <> /etc/motd Installation failed. Please see \$logfile for details of failure EOF if [ -d /etc/platform ] ; then echo \$logfile >/etc/platform/installation_failed fi echo -e '\n\nInstallation failed.\n' cat \$logfile exit 1 } function get_http_port() { echo \$(cat /proc/cmdline |xargs -n1 echo |grep '^inst.repo=' | sed -r 's#^[^/]*://[^/]*:([0-9]*)/.*#\1#') } function get_disk_dev() { local disk # Detect HDD for blk_dev in vda vdb sda sdb dda ddb hda hdb; do if [ -d /sys/block/\$blk_dev ]; then disk=\$(ls -l /sys/block/\$blk_dev | grep -v usb | head -n1 | sed 's/^.*\([vsdh]d[a-z]\+\).*$/\1/'); if [ -n "\$disk" ]; then exec_retry 3 0.5 "multipath -c /dev/\$disk" > /dev/null && continue echo "\$disk" return fi fi done for blk_dev in nvme0n1 nvme1n1; do if [ -d /sys/block/\$blk_dev ]; then disk=\$(ls -l /sys/block/\$blk_dev | grep -v usb | head -n1 | sed 's/^.*\(nvme[01]n1\).*$/\1/'); if [ -n "\$disk" ]; then echo "\$disk" return fi fi done for mpath_dev in mpatha mpathb; do if [ -e /dev/mapper/\$mpath_dev ]; then echo "/dev/mapper/\$mpath_dev" return fi done } 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 } function exec_retry() { local retries=\$1 local interval=\$2 local cmd=\$3 let -i retry_count=1 local ret_code=0 local ret_stdout="" cmd="\$cmd" # 2>&\$stdout" while [ \$retry_count -le \$retries ]; do #wlog "Running command: '\$cmd'." ret_stdout=\$(eval \$cmd) ret_code=\$? [ \$ret_code -eq 0 ] && break wlog "Error running command '\${cmd}'. Try \${retry_count} of \${retries} at \${interval}s." wlog "ret_code: \${ret_code}, stdout: '\${ret_stdout}'." sleep \$interval let retry_count++ done echo "\${ret_stdout}" return \${ret_code} } # This is a developer debug tool that can be line inserted in any kickstart. # Code should not be committed with a call to this function. # When inserted and hit, execution will stall until one of the 2 conditions: # 1. /tmp/wait_for_go file is removed 'manually' # 2. or after 10 minutes function wait_for_go() { touch /tmp/wait_for_go for loop in {1..60} ; do sleep 10 if [ ! -e "/tmp/wait_for_go" ] ; then break fi done } END_FUNCTIONS %end # Template from: pre_common_head.cfg %pre --erroronfail # Source common functions . /tmp/ks-functions.sh # First, parse /proc/cmdline to find the boot args set -- `cat /proc/cmdline` for I in $*; do case "$I" in *=*) eval $I 2>/dev/null;; esac; done # Source the custom setup script if it exists if [ -e /run/install/repo/ks-setup.cfg ]; then source /run/install/repo/ks-setup.cfg fi append= if [ -n "$console" ] ; then append="console=$console" fi if [ -n "$security_profile" ]; then append="$append security_profile=$security_profile" fi #### SECURITY PROFILE HANDLING (Pre Installation) #### if [ -n "$security_profile" ] && [ "$security_profile" == "extended" ]; then # IMA specific boot options: # Enable Kernel auditing append="$append audit=1" else # we need to blacklist the IMA and Integrity Modules # on standard security profile append="$append module_blacklist=integrity,ima" # Disable Kernel auditing in Standard Security Profile mode append="$append audit=0" fi if [ -n "$tboot" ]; then append="$append tboot=$tboot" else append="$append tboot=false" fi if [ -z "$boot_device" ]; then boot_device=$(get_disk_dev) fi boot_device_arg= if [ -n "$boot_device" ] ; then boot_device_arg="--boot-drive=$(get_by_path $boot_device)" fi echo "bootloader --location=mbr $boot_device_arg --timeout=5 --append=\"$append\"" > /tmp/bootloader-include echo "timezone --nontp --utc UTC" >/tmp/timezone-include %end #version=DEVEL install lang en_US.UTF-8 keyboard us %include /tmp/timezone-include # set to 'x' so we can use shadow password rootpw --iscrypted x selinux --disabled authconfig --enableshadow --passalgo=sha512 firewall --service=ssh # The following is the partition information you requested # Note that any partitions you deleted are not expressed # here so unless you clear all partitions first, this is # not guaranteed to work zerombr # Disk layout from %pre %include /tmp/part-include # Bootloader parms from %pre %include /tmp/bootloader-include reboot --eject %addon com_redhat_kdump --enable --reserve-mb=512 %end # Template from: pre_pkglist.cfg %packages @core @base -kernel-module-igb-uio-rt -kernel-module-wrs-avp-rt -kernel-rt -kernel-rt-kvm -kernel-rt-modules-extra -kernel-rt-tools -kernel-rt-tools-libs -kmod-bnxt_en-rt -kmod-drbd-rt -kmod-e1000e-rt -kmod-i40e-rt -kmod-ixgbe-rt -kmod-tpm-rt -mlnx-ofa_kernel -mlnx-ofa_kernel-rt -mlnx-ofa_kernel-rt-modules -qat16-rt @platform-controller @updates-controller %end # Template from: pre_disk_setup_common.cfg %pre --erroronfail # Get the FD used by subshells to log output exec {stdout}>&1 # Source common functions . /tmp/ks-functions.sh wlog "ISO_DEV='$ISO_DEV'." wlog "USB_DEV='$USB_DEV'." # This is a really fancy way of finding the first usable disk for the # install and not stomping on the USB device if it comes up first # First, parse /proc/cmdline to find the boot args set -- `cat /proc/cmdline` for I in $*; do case "$I" in *=*) eval $I 2>/dev/null;; esac; done # Source the custom setup script if it exists if [ -e /run/install/repo/ks-setup.cfg ]; then source /run/install/repo/ks-setup.cfg fi if [ -z "$boot_device" ]; then boot_device=$(get_disk_dev) fi if [ -z "$rootfs_device" ]; then rootfs_device=$(get_disk_dev) fi if [ -z "$persistent_size" ]; then # Default backup partition size in MiB persistent_size=30000 fi # Get root and boot devices orig_rootfs_device=$rootfs_device by_path_rootfs_device=$(get_by_path $rootfs_device) rootfs_device=$(get_disk $by_path_rootfs_device) wlog "Found rootfs $orig_rootfs_device on: $by_path_rootfs_device->$rootfs_device." orig_boot_device=$boot_device by_path_boot_device=$(get_by_path $boot_device) boot_device=$(get_disk $by_path_boot_device) wlog "Found boot $orig_boot_device on: $by_path_boot_device->$boot_device." # Check if boot and rootfs devices are valid if [ ! -e "$rootfs_device" -o ! -e "$boot_device" ] ; then # Touch this file to prevent Anaconda from dying an ungraceful death touch /tmp/part-include report_pre_failure_with_msg "ERROR: Specified installation ($orig_rootfs_device) or boot ($orig_boot_device) device is invalid." 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 we should avoid using # them while performing partition operations. STOR_DEVS="" wlog "Detected storage devices:" for f in /dev/disk/by-path/*; do dev=$(readlink -f $f) exec_retry 2 0.5 "lsblk --nodeps --pairs $dev" | grep -q 'TYPE="disk"' if [ $? -eq 0 ]; then exec_retry 3 0.5 "multipath -c $dev" > /dev/null if [ $? -eq 0 ]; then mpath_dev=/dev/mapper/$(exec_retry 3 0.5 "multipath -l $dev" | head -n1 | cut -d " " -f 1) if echo $STOR_DEVS | grep -q -w $mpath_dev; then continue else STOR_DEVS="$STOR_DEVS $mpath_dev" mpath_path=$(find -L /dev/disk/by-id/dm-uuid* -samefile $mpath_dev) wlog " ${mpath_path}->${mpath_dev}" fi else STOR_DEVS="$STOR_DEVS $dev" wlog " ${f}->${dev}" fi 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) wlog "Unique storage devices: $STOR_DEVS." if [ -z "$STOR_DEVS" ] then report_pre_failure_with_msg "ERROR: 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. STOR_DEV_FDS="$stdout" for dev in $STOR_DEVS; do exec {fd}>$dev || report_pre_failure_with_msg "ERROR: Error creating file descriptor for $dev." flock -n "$fd" || report_pre_failure_with_msg "ERROR: Can't get a lock on fd $fd of device $dev." STOR_DEV_FDS="$STOR_DEV_FDS $fd" done # Log info about system state at beginning of partitioning operation for dev in $STOR_DEVS; do wlog "Initial partition table for $dev is:" parted -s $dev unit mib print done # Ensure specified device is not a USB drive udevadm info --query=property --name=$rootfs_device |grep -q '^ID_BUS=usb' || \ udevadm info --query=property --name=$boot_device |grep -q '^ID_BUS=usb' if [ $? -eq 0 ]; then # Touch this file to prevent Anaconda from dying an ungraceful death touch /tmp/part-include report_pre_failure_with_msg "ERROR: Specified installation ($orig_rootfs_device) or boot ($orig_boot_device) device is a USB drive." fi # Deactivate existing volume groups to avoid Anaconda issues with pre-existing groups vgs=$(exec_no_fds "$STOR_DEV_FDS" "vgs --noheadings -o vg_name") for vg in $vgs; do wlog "Disabling $vg." exec_no_fds "$STOR_DEV_FDS" "vgchange -an $vg" 5 0.5 [ $? -ne 0 ] && report_pre_failure_with_msg "ERROR: Failed to disable $vg." done # Remove the volume groups that have physical volumes on the root disk for vg in $(exec_no_fds "$STOR_DEV_FDS" "vgs --noheadings -o vg_name"); do exec_no_fds "$STOR_DEV_FDS" "pvs --select \"vg_name=$vg\" --noheadings -o pv_name" | grep -q "$rootfs_device" if [ $? -ne 0 ]; then wlog "Found $vg with no PV on rootfs, ignoring." continue fi wlog "Removing LVs on $vg." exec_no_fds "$STOR_DEV_FDS" "lvremove --force $vg" 5 0.5 || wlog "WARNING: Failed to remove lvs on $vg." pvs=$(exec_no_fds "$STOR_DEV_FDS" "pvs --select \"vg_name=$vg\" --noheadings -o pv_name") wlog "VG $vg has PVs: $(echo $pvs), removing them." for pv in $pvs; do wlog "Removing PV $pv." exec_no_fds "$STOR_DEV_FDS" "pvremove --force --force --yes $pv" 5 0.5 [ $? -ne 0 ] && report_pre_failure_with_msg "ERROR: Failed to remove PV." done # VG should no longer be present vg_check=$(exec_no_fds "$STOR_DEV_FDS" "vgs --select \"vg_name=$vg\" --noheadings -o vg_name") if [ -n "$vg_check" ]; then wlog "WARNING: VG $vg is still present after removing PVs! Removing it by force." exec_no_fds "$STOR_DEV_FDS" "vgremove --force $vg" 5 0.5 [ $? -ne 0 ] && report_pre_failure_with_msg "ERROR: Failed to remove VG." fi done ONLYUSE_HDD="" part_type_guid_str="Partition GUID code" 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 $rootfs_device" WIPE_HDD=$rootfs_device ONLYUSE_HDD="$(basename $rootfs_device)" if [ "$rootfs_device" != "$boot_device" ]; then WIPE_HDD="$WIPE_HDD,$boot_device" ONLYUSE_HDD="$ONLYUSE_HDD,$(basename $boot_device)" fi else # Make a list of all the hard drives that are to be wiped WIPE_HDD="" # Partition type OSD has a unique globally identifier CEPH_REGULAR_OSD_GUID="4FBD7E29-9D25-41B8-AFD0-062C0CEFF05D" CEPH_REGULAR_JOURNAL_GUID="45B0969E-9B03-4F30-B4C6-B4B80CEFF106" CEPH_MPATH_OSD_GUID="4FBD7E29-8AE0-4982-BF9D-5A8D867AF560" CEPH_MPATH_JOURNAL_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 wlog "Wipe OSD data." WIPE_CEPH_OSDS="true" else wlog "Skip Ceph OSD data wipe." WIPE_CEPH_OSDS="false" fi for dev in $STOR_DEVS do # 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" pvs | grep -q "$dev *ceph" if [ $? -eq 0 ]; then wlog "skip rook provisoned disk $dev" continue fi part_numbers=( `parted -s $dev print | awk '$1 == "Number" {i=1; next}; i {print $1}'` ) # Scanning the partitions looking for CEPH OSDs and # skipping any disk found with such partitions for part_number in "${part_numbers[@]}"; do sgdisk_part_info=$(sgdisk -i $part_number $dev) part_type_guid=$(echo "$sgdisk_part_info" | grep "$part_type_guid_str" | awk '{print $4;}') if [ "$part_type_guid" == $CEPH_REGULAR_OSD_GUID -o "$part_type_guid" == $CEPH_MPATH_OSD_GUID ]; then wlog "OSD found on $dev, skipping wipe" wipe_dev="false" break fi pvs | grep -q -e "${dev}${part_number} *ceph" -e "${dev}p${part_number} *ceph" if [ $? -eq 0 ]; then wlog "Rook OSD found on $dev$part_number, skip wipe" wipe_dev="false" break fi done if [ "$wipe_dev" == "false" ]; then continue fi fi # Add device to the wipe list devname=$(basename $dev) if [ -e $dev -a "$ISO_DEV" != "../../$devname" -a "$USB_DEV" != "../../$devname" ]; then if [ -n "$WIPE_HDD" ]; then WIPE_HDD=$WIPE_HDD,$dev else WIPE_HDD=$dev fi fi done wlog "Not in upgrade, wiping disks: $WIPE_HDD" fi ROOTFS_PART_PREFIX=$rootfs_device #check if disk is nvme case $rootfs_device in *"nvme"*) ROOTFS_PART_PREFIX=${ROOTFS_PART_PREFIX}p ;; esac BACKUP_CREATED=0 # 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_LABEL="Platform Backup" BACKUP_PART_GUID="BA5EBA11-0000-1111-2222-000000000002" for dev in ${WIPE_HDD//,/ } do # Clearing previous GPT tables or LVM data # Delete the first few bytes at the start and end of the partition. This is required with # GPT partitions, they save partition info at the start and the end of the block. # Do this for each partition on the disk, as well. part_numbers=( $(parted -s $dev print | awk '$1 == "Number" {i=1; next}; i {print $1}') ) wlog "WIPE_HDD: checking dev: $dev, part_numbers: $part_numbers, rootfs_device: $rootfs_device, boot_device: $boot_device" for part_number in "${part_numbers[@]}"; do part=$dev$part_number case $part in *"nvme"*) part=${dev}p${part_number} ;; esac sgdisk_part_info=$(sgdisk -i $part_number $dev) part_type_guid=$(echo "$sgdisk_part_info" | grep "$part_type_guid_str" | awk '{print $4;}') if [ "$dev" = "$rootfs_device" ] || [ "$dev" = "$boot_device" ]; then wlog "Checking for backup partition: $part" part_fstype=$(exec_retry 5 0.5 "blkid -s TYPE -o value $part") if [ "$part_type_guid" = "$BACKUP_PART_GUID" ] && [ "${part_fstype}" = "ext4" ]; then wlog "Skipping wipe backup partition $part" BACKUP_CREATED=1 continue else wlog "Skipping part:$part_number $dev GUID: $part_type_guid" fi fi wlog "Wiping partition $part" if [[ $WIPE_CEPH_OSDS == "true" && ( "$part_type_guid" == $CEPH_REGULAR_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. dd if=/dev/zero of=$part bs=1M count=100 dd if=/dev/zero of=$part bs=1M count=100 seek=$(( `blockdev --getsz $part` / (1024 * 2) - 100 )) else dd if=/dev/zero of=$part bs=512 count=34 dd if=/dev/zero of=$part bs=512 count=34 seek=$((`blockdev --getsz $part` - 34)) fi exec_retry 5 0.5 "parted -s $dev rm $part_number" # LP 1876374: On some nvme systems udev doesn't correctly remove the # links to the deleted partitions from /dev/nvme* causing them to be # seen as non block devices. exec_retry 5 0.3 "rm -f $part" # Delete remaining /dev node leftover done if [ $BACKUP_CREATED -eq 0 -o "$dev" != "$rootfs_device" ]; then wlog "Creating disk label for $dev" parted -s $dev mktable gpt fi done # Check for remaining cgts-vg PVs, which could potentially happen # in an upgrade where we're not wiping all disks. # If we ever create other volume groups from kickstart in the future, # include them in this search as well. partitions=$(exec_no_fds "$STOR_DEV_FDS" "pvs --select 'vg_name=cgts-vg' -o pv_name --noheading" | grep -v '\[unknown\]') for p in $partitions do wlog "Pre-wiping $p from kickstart (cgts-vg present)" dd if=/dev/zero of=$p bs=512 count=34 dd if=/dev/zero of=$p bs=512 count=34 seek=$((`blockdev --getsz $p` - 34)) done let -i gb=1024*1024*1024 if [ -n "$ONLYUSE_HDD" ]; then cat<>/tmp/part-include ignoredisk --only-use=$ONLYUSE_HDD EOF fi # Template from: pre_disk_controller.cfg ## NOTE: updates to partition sizes need to be also reflected in ## _controller_filesystem_limits() in sysinv/api/controllers/v1/istorconfig.py ROOTFS_SIZE=20000 LOG_VOL_SIZE=8000 SCRATCH_VOL_SIZE=16000 BOOT_SIZE=500 EFI_SIZE=300 PLATFORM_BACKUP_SIZE=$persistent_size ROOTFS_OPTIONS="defaults" profile_mode=`cat /proc/cmdline |xargs -n1 echo |grep security_profile= | grep extended` if [ -n "$profile_mode" ]; then # Enable iversion labelling for rootfs when IMA is enabled ROOTFS_OPTIONS="${ROOTFS_OPTIONS},iversion" fi if [ -d /sys/firmware/efi ] ; then BACKUP_PART=${ROOTFS_PART_PREFIX}1 BACKUP_PART_NO=1 START_POINT=1 END_POINT=$(($START_POINT + $PLATFORM_BACKUP_SIZE)) BACKUP_END_POINT=$END_POINT if [ $BACKUP_CREATED -eq 0 ] ; then wlog "Creating platform backup partition of ${PLATFORM_BACKUP_SIZE}MiB from ${START_POINT}MiB to ${END_POINT}MiB." exec_retry 5 0.5 "parted -s $rootfs_device mkpart primary ext4 ${START_POINT}MiB ${END_POINT}MiB" [ $? -ne 0 ] && report_pre_failure_with_msg "ERROR: Partition creation failed!" fi START_POINT=$END_POINT END_POINT=$(($START_POINT + $EFI_SIZE)) wlog "Creating EFI partition of ${EFI_SIZE}MiB from ${START_POINT}MiB to ${END_POINT}MiB." exec_retry 5 0.5 "parted -s $rootfs_device mkpart primary fat32 ${START_POINT}MiB ${END_POINT}MiB" [ $? -ne 0 ] && report_pre_failure_with_msg "ERROR: Partition creation failed!" cat<>/tmp/part-include part /boot/efi --fstype=efi --onpart=${ROOTFS_PART_PREFIX}2 EOF else BACKUP_PART=${ROOTFS_PART_PREFIX}2 BACKUP_PART_NO=2 wlog "Creating 1MB BIOS GRUB partition from 1MiB to 2MiB." exec_retry 5 0.5 "parted -s $rootfs_device mkpart primary 1MiB 2MiB" [ $? -ne 0 ] && report_pre_failure_with_msg "ERROR: Partition creation failed!" START_POINT=2 END_POINT=$(($START_POINT + $PLATFORM_BACKUP_SIZE)) BACKUP_END_POINT=$END_POINT if [ $BACKUP_CREATED -eq 0 ] ; then wlog "Creating platform backup partition of ${PLATFORM_BACKUP_SIZE}MiB from ${START_POINT}MiB to ${END_POINT}MiB." exec_retry 5 0.5 "parted -s $rootfs_device mkpart primary ext4 ${START_POINT}MiB ${END_POINT}MiB" [ $? -ne 0 ] && report_pre_failure_with_msg "ERROR: Partition creation failed!" fi cat<>/tmp/part-include part biosboot --asprimary --fstype=biosboot --onpart=${ROOTFS_PART_PREFIX}1 EOF fi START_POINT=$END_POINT END_POINT=$(($START_POINT + $BOOT_SIZE)) wlog "Creating boot partition of ${BOOT_SIZE}MiB from ${START_POINT}MiB to ${END_POINT}MiB." exec_retry 5 0.5 "parted -s $rootfs_device mkpart primary ext4 ${START_POINT}MiB ${END_POINT}MiB" [ $? -ne 0 ] && report_pre_failure_with_msg "ERROR: Partition creation failed!" START_POINT=$END_POINT END_POINT=$(($START_POINT + $ROOTFS_SIZE)) wlog "Creating rootfs partition of ${ROOTFS_SIZE}MiB from ${START_POINT}MiB to ${END_POINT}MiB." exec_retry 5 0.5 "parted -s $rootfs_device mkpart primary ext4 ${START_POINT}MiB ${END_POINT}MiB" [ $? -ne 0 ] && report_pre_failure_with_msg "ERROR: Partition creation failed!" START_POINT=$END_POINT wlog "Creating cgcs-vg partition of ${CGCS_PV_SIZE}MiB from ${START_POINT}MiB to 100%." exec_retry 5 0.5 "parted -s $rootfs_device mkpart extended ${START_POINT}MiB 100%" [ $? -ne 0 ] && report_pre_failure_with_msg "ERROR: Partition creation failed!" if [ $BACKUP_CREATED -ne 0 ] ; then BACKUP_CURRENT_SIZE=$(parted -s $BACKUP_PART unit MiB print | grep $BACKUP_PART | awk '{print $3}' | sed 's/[^C0-9]*//g') if [ $BACKUP_CURRENT_SIZE -lt $PLATFORM_BACKUP_SIZE ] ; then wlog "Backup partition size is ${BACKUP_CURRENT_SIZE}MiB, resizing to ${PLATFORM_BACKUP_SIZE}MiB." # parted will throw an error about overlapping with the next partition if we don't do this BACKUP_END_POINT=$(($BACKUP_END_POINT - 1)).9 exec_retry 5 0.5 "parted -s $rootfs_device resizepart $BACKUP_PART_NO ${BACKUP_END_POINT}MiB" [ $? -ne 0 ] && report_pre_failure_with_msg "ERROR: resize of platform backup partition failed!" exec_retry 2 0.1 "e2fsck -p -f $BACKUP_PART" [ $? -ne 0 ] && report_pre_failure_with_msg "ERROR: e2fsck failed on platform backup partition!" exec_retry 2 1 "resize2fs $BACKUP_PART" [ $? -ne 0 ] && report_pre_failure_with_msg "ERROR: Filed to resize ext4 fs of platform backup partition!" elif [ $BACKUP_CURRENT_SIZE -gt $PLATFORM_BACKUP_SIZE ] ; then report_pre_failure_with_msg "ERROR: Backup partition is ${BACKUP_CURRENT_SIZE}MiB expected size is less or equal to ${PLATFORM_BACKUP_SIZE}MiB." else wlog "Backup partition size is correct: ${PLATFORM_BACKUP_SIZE}MiB." fi cat<>/tmp/part-include part /opt/platform-backup --fstype=ext4 --asprimary --noformat --onpart=$BACKUP_PART --fsoptions="$ROOTFS_OPTIONS" EOF else cat</tmp/backup-guid-change.sh echo "\$(date '+%Y-%m-%d %H:%M:%S.%3N') - Updating backup partition GUID." flock $rootfs_device sgdisk --change-name=${BACKUP_PART_NO}:"${BACKUP_PART_LABEL}" --typecode=${BACKUP_PART_NO}:"${BACKUP_PART_GUID}" $rootfs_device || exit 1 EOF cat<>/tmp/part-include part /opt/platform-backup --fstype=ext4 --asprimary --onpart=$BACKUP_PART --fsoptions="$ROOTFS_OPTIONS" EOF fi cat<>/tmp/part-include part /boot --fstype=ext4 --asprimary --onpart=${ROOTFS_PART_PREFIX}3 --fsoptions="$ROOTFS_OPTIONS" part pv.253004 --onpart=${ROOTFS_PART_PREFIX}5 volgroup cgts-vg --pesize=32768 pv.253004 logvol /var/log --fstype=ext4 --vgname=cgts-vg --size=$LOG_VOL_SIZE --name=log-lv logvol /scratch --fstype=ext4 --vgname=cgts-vg --size=$SCRATCH_VOL_SIZE --name=scratch-lv part / --fstype=ext4 --asprimary --onpart=${ROOTFS_PART_PREFIX}4 --fsoptions="$ROOTFS_OPTIONS" EOF # Template from: pre_disk_setup_tail.cfg # Log info about system state at end of partitioning operation. for dev in $STOR_DEVS; do wlog "Partition table at end of script for $dev is:" parted -s $dev unit mib print done # Close all FDs and wait for udev to reshuffle all partitions. wlog "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_pre_failure_with_msg "ERROR: udevadm settle failed!" # Rescan LVM cache to avoid warnings for VGs that were recreated. pvscan --cache %end # Template from: post_platform_conf_controller.cfg %post --erroronfail # Source common functions . /tmp/ks-functions.sh # Set the security profile mode secprofile="standard" profile_mode=`cat /proc/cmdline |xargs -n1 echo |grep security_profile= | grep extended` if [ -n "$profile_mode" ]; then secprofile="extended" fi mkdir -p -m 0775 /etc/platform cat < /etc/platform/platform.conf nodetype=controller subfunction=controller system_type=Standard security_profile=$secprofile EOF %end # Template from: post_common.cfg %post --nochroot --erroronfail # Source common functions . /tmp/ks-functions.sh # Change GUID of backup partition change_guid=/tmp/backup-guid-change.sh if [ -f "$change_guid" ]; then sh $change_guid || report_post_failure_with_logfile "ERROR: Failed to update platform backup GUID" fi %end %post --erroronfail # Source common functions . /tmp/ks-functions.sh # Turn off locale support for i18n if is not installed if [ ! -d /usr/share/i18n ] ; then rm -f /etc/sysconfig/i18n fi # Unset the hostname rm /etc/hostname # 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 #### SECURITY PROFILE HANDLING (Post Installation) #### # Check if the Security profile mode is enabled # and load the appropriate kernel modules secprofile=`cat /proc/cmdline |xargs -n1 echo |grep security_profile= | grep extended` if [ -n "$secprofile" ]; then echo "In Extended Security profile mode. Loading IMA kernel module" systemctl enable auditd.service # Add the securityfs mount for the IMA Runtime measurement list echo "securityfs /sys/kernel/security securityfs defaults,nodev 0 0" >> /etc/fstab else # Disable audit daemon in the Standard Security Profile systemctl disable auditd fi . /etc/platform/platform.conf # Delete the CentOS yum repo files rm -f /etc/yum.repos.d/CentOS-* # Create platform yum repo file cat >/etc/yum.repos.d/platform.repo < /etc/udev/rules.d/70-persistent-net.rules for dir in /sys/class/net/*; do if [ -e ${dir}/device ]; then dev=$(basename ${dir}) mac_address=$(cat /sys/class/net/${dev}/address) echo "ACTION==\"add\", SUBSYSTEM==\"net\", DRIVERS==\"?*\", ATTR{address}==\"${mac_address}\", NAME=\"${dev}\"" >> /etc/udev/rules.d/70-persistent-net.rules fi done # Mark the sysadmin password as expired immediately chage -d 0 sysadmin # Lock the root password passwd -l root # Enable tmpfs mount for /tmp # delete /var/tmp so that it can similinked in rm -rf /var/tmp systemctl enable tmp.mount # Disable automount of /dev/hugepages systemctl mask dev-hugepages.mount # Disable firewall systemctl disable firewalld # Disable libvirtd systemctl disable libvirtd.service # Enable rsyncd systemctl enable rsyncd.service # Allow root to run sudo from a non-tty (for scripts running as root that run sudo cmds) echo 'Defaults:root !requiretty' > /etc/sudoers.d/root # Make fstab just root read/writable chmod 600 /etc/fstab # Create first_boot flag touch /etc/platform/.first_boot %end # Template from: post_kernel_controller.cfg %post --erroronfail # Source common functions . /tmp/ks-functions.sh ## Custom kernel options KERN_OPTS=" 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. ## KERN_OPTS="${KERN_OPTS} loop.max_part=15" ## Add kernel options to ensure an selinux is disabled KERN_OPTS="${KERN_OPTS} selinux=0 enforcing=0" # Add kernel options to ensure NMI watchdog is enabled, if supported KERN_OPTS="${KERN_OPTS} nmi_watchdog=panic,1 softlockup_panic=1" # Add kernel option to panic on a softdog timeout KERN_OPTS="${KERN_OPTS} softdog.soft_panic=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 KERN_OPTS="${KERN_OPTS} biosdevname=0" fi # k8s updates #KERN_OPTS="${KERN_OPTS} cgroup_disable=memory" KERN_OPTS="${KERN_OPTS} user_namespace.enable=1" # 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) grep -q 'nopti' /proc/cmdline if [ $? -eq 0 ]; then KERN_OPTS="${KERN_OPTS} nopti" fi grep -q 'nospectre_v2' /proc/cmdline if [ $? -eq 0 ]; then KERN_OPTS="${KERN_OPTS} nospectre_v2" fi grep -q 'nospectre_v1' /proc/cmdline if [ $? -eq 0 ]; then KERN_OPTS="${KERN_OPTS} nospectre_v1" fi perl -pi -e 's/(GRUB_CMDLINE_LINUX=.*)\"/\1'"$KERN_OPTS"'\"/g' /etc/default/grub if [ -d /sys/firmware/efi ] ; then grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg else grub2-mkconfig -o /boot/grub2/grub.cfg fi %end # Template from: post_lvm_pv_on_rootfs.cfg %post --erroronfail # Source common functions . /tmp/ks-functions.sh # 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 # Determine which disk we created our PV on (i.e. the root disk) ROOTDISK=$(get_by_path $(pvdisplay --select 'vg_name=cgts-vg' -C -o pv_name --noheadings)) if [ -z "$ROOTDISK" ]; then report_post_failure_with_msg "ERROR: failed to identify rootdisk via pvdisplay" fi # Edit the LVM config so LVM only looks for LVs on the root disk sed -i "s#^\( *\)global_filter = \[.*#\1global_filter = [ \"a|${ROOTDISK}|\", \"r|.*|\" ]#" /etc/lvm/lvm.conf %end # Template from: post_miniboot_controller.cfg %pre --erroronfail ############################################################################ # # This miniboot kickstart tells Anaconda to install the subcloud # from one of the following repo sources listed in order of priority. # # 1. Prestaged Content ; Packages and repodata (highest priority) # # prestaged source ... /opt/platform-backup/rel-xx.xx/Packages # prestaged source ... /opt/platform-backup/rel-xx.xx/repodata # prestaged source ... xxxHTTP_URLxxx/patches # # Anaconda install ... /opt/platform-backup/rel-xx.xx # # 2. Prestaged ISO image # # prestaged source ... /opt/platform-backup/rel-xx.xx/bootimage.iso # prestaged check ... /opt/platform-backup/rel-xx.xx/bootimage.md5 # prestaged source ... xxxHTTP_URLxxx/patches # # Anaconda install ... /mnt/bootimage # # 3. Staged feeds after %pre fetch from System Controller (lowest priority) # # stage source wget xxxHTTP_URLxxx/Packages -> /mnt/install/repo/Packages # stage source wget xxxHTTP_URLxxx/repodata -> /mnt/install/repo/repodata # stage source wget xxxHTTP_URLxxx/patches -> /mnt/install/repo/patches # # Anaconda install ... /mnt/install/repo/ # # All of the above methods must mirror the system controller's feed, # updates and patching repos from the staged or prestaged source. # # feed .... for installing system nodes /www/pages/feed/rel-xx.xx # # updates ... for managing updates /www/pages/updates # # patching .. for managing patches /opt/patching/commit # /opt/patching/available # /opt/patching/applied # # Miniboot checks and reports on found prestaged container images or # other files with md5 checks present. Miniboot leaves them to be # utilized by software. # # prestaged container images ... /opt/platform-backup/rel-xx.xx/image# # prestaged image checks ... /opt/platform-backup/rel-xx.xx/image#.md5 # ############################################################################ # Source common functions . /tmp/ks-functions.sh SW_VERSION=21.12 STAGING_DIR="platform-backup" BACKUP_DEVICE= BACKUP_PART_GUID="BA5EBA11-0000-1111-2222-000000000002" BACKUP_MOUNT=/mnt/${STAGING_DIR} BOOTIMAGE_ISO="" # Staging and Prestaging Directories INSTALL_MOUNT=/mnt/install/repo BOOTIMAGE_MOUNT=/mnt/bootimage PRESTAGE_DIR=${BACKUP_MOUNT}/${SW_VERSION} KS="Miniboot pre:" wlog "${KS} Local Install check" iso_check=false iso_mount=false prestaging_files=false # Search for a backup partition, using GUID (which appears lower case in the blkid output): while read -r device_path; do if [ "$(blkid -p "${device_path}" | grep -c -i "${BACKUP_PART_GUID}")" -gt 0 ]; then BACKUP_DEVICE=${device_path} wlog "Found backup device: ${BACKUP_DEVICE}" break fi done <<<"$(lsblk --noheadings --list --path --output NAME)" # Look for and validate the local iso image if [ -n "${BACKUP_DEVICE}" ] && [ -e "${BACKUP_DEVICE}" ]; then mkdir -p ${BACKUP_MOUNT} mount ${BACKUP_DEVICE} ${BACKUP_MOUNT} 2>/dev/null rc=$? if [ $rc -eq 0 ] ; then sleep 2 # does the prestaging dir for the specified sw version exist if [ -d "${BACKUP_MOUNT}/${SW_VERSION}" ] ; then # are there files in it ? if [ "$(ls -A ${BACKUP_MOUNT}/${SW_VERSION})" ] ; then # change to prestaging dir and load the file names cd ${BACKUP_MOUNT}/${SW_VERSION} # Local Install Bundle Validation: # # ISO Image: There must be an iso image whose base # filename matches an md5 check file and # that check must pass. # # Container Images: Missing container image check file(s) or # container image validation check failure # does not reject a Local Install. # # Find the iso image first. # - there should be only one so use the first one found # just in case there are others there. # Loop over the files if there are any looking for the iso iso_filename="" for file in $(ls -A .) ; do prestaging_files=true filename="${file%.*}" extension="${file##*.}" if [ "${extension}" = "iso" ] ; then iso_filename="${filename}" # Found the iso name for the mount operation below BOOTIMAGE_ISO=${BACKUP_MOUNT}/${SW_VERSION}/${file} wlog "${KS} found prestaged iso image ${BOOTIMAGE_ISO}" if [ -f ${filename}.md5 ] ; then md5sum -c "${filename}.md5" if [ $? -eq 0 ] ; then wlog "${KS} ${file} iso check passed" iso_check=true mkdir -p ${BOOTIMAGE_MOUNT} mount -o loop ${BOOTIMAGE_ISO} ${BOOTIMAGE_MOUNT} if [ $? -eq 0 ] ; then iso_mount=true wlog "${KS} local iso mounted ${BOOTIMAGE_MOUNT}" else wlog "${KS} local iso mount failed" fi else wlog "${KS} ${file} iso check failed" fi else wlog "${KS} no iso image check file found ${filename}.md5" fi break fi done # Loop over the files again this time to run checks # on md5 files that are not the iso. # Such files are expected to be checks for container image sets. # Failure of container image sets check will not reject # the local install. for file in $(ls -A .) ; do prestaging_files=true filename="${file%.*}" extension="${file##*.}" if [ "${extension}" = "md5" -a "${filename}" != "${iso_filename}" ] ; then wlog "${KS} prestaged file : ${file}" md5sum -c "${file}" if [ $? -eq 0 ] ; then wlog "${KS} ${file} check passed" else wlog "${KS} ${file} check failed" fi fi done fi if [ "${prestaging_files}" = false ] ; then wlog "${KS} no prestaged files" fi else wlog "${KS} ${BACKUP_MOUNT} not mounted" fi else wlog "${KS} mount of '${BACKUP_DEVICE}' to ${BACKUP_MOUNT} failed rc:$rc" fi else wlog "${KS} backup device '${BACKUP_DEVICE}' does not exist" fi wlog "${KS} iso_check: ${iso_check} iso_mount: ${iso_mount}" if [ "${iso_check}" = true -a "${iso_mount}" = true ] ; then wlog "${KS} Local Install ready" elif [ "${iso_mount}" = false ] ; then wlog "${KS} Prestaged ISO not present or invalid" fi # Make sure the prestage directory exists, as well as the required subdirectories. exists_prestage=false wlog "${KS} Checking prestaged content PRESTAGE_DIR: ${PRESTAGE_DIR}" if [ ! -e ${PRESTAGE_DIR} ] || [ ! -e ${PRESTAGE_DIR}/Packages ] || [ ! -e ${PRESTAGE_DIR}/repodata ]; then exists_prestage=false wlog "${KS} Prestaged content not present" else repodata_files_count=$(ls ${PRESTAGE_DIR}/repodata | wc -l) if [ ${repodata_files_count} -ne 0 ]; then packages_files_count=$(ls ${PRESTAGE_DIR}/Packages | wc -l) if [ ${packages_files_count} -ne 0 ] ; then exists_prestage=true wlog "${KS} Prestaged content present" # unmount iso image if mounted if [ -d ${BOOTIMAGE_MOUNT} ]; then wlog "${KS} Unmounting ${BOOTIMAGE_MOUNT} for prestaged content install" umount ${BOOTIMAGE_MOUNT} rmdir ${BOOTIMAGE_MOUNT} else wlog "${KS} ${BOOTIMAGE_MOUNT} dir does not exist" fi else wlog "${KS} Prestaged Content is invalid ; no Package files present" fi else wlog "${KS} Prestaged Content is invalid ; no repodata files present ${repodata_files_count}" fi fi # # This controls where the packages come from. # Lower cost has higher priority ; making local install preferred. # # If ${BOOTIMAGE_MOUNT} exists then install from local iso - Local Install # Otherwise, they are fetched from platform backup if the Packages have been # prestaged. # If this fails, they are fetched from the System Controller - Remote Install # if [ "${exists_prestage}" = true ]; then wlog "${KS} Prestage directory found: ${PRESTAGE_DIR}. Proceeding with prestaged install." cat << EOF > /tmp/repo-include repo --name=local-base --cost=100 --baseurl=file://${PRESTAGE_DIR}/ repo --name=local-updates --cost=100 --baseurl=file://${PRESTAGE_DIR}/patches/ repo --name=remote-base --cost=200 --baseurl=xxxHTTP_URLxxx/ repo --name=remote-updates --cost=200 --baseurl=xxxHTTP_URLxxx/patches/ EOF elif [ "${iso_check}" = true ] && [ "${iso_mount}" = true ] ; then wlog "${KS} Packages will be retrieved from prestage ISO. Proceeding with local (ISO) install." cat << EOF > /tmp/repo-include repo --name=local-base --cost=100 --baseurl=file://${BOOTIMAGE_MOUNT}/ repo --name=local-updates --cost=100 --baseurl=file://${BOOTIMAGE_MOUNT}/patches/ repo --name=remote-base --cost=200 --baseurl=xxxHTTP_URLxxx/ repo --name=remote-updates --cost=200 --baseurl=xxxHTTP_URLxxx/patches/ EOF else # Mirror remote software repositories wlog "${KS} Staging Repo via ${feed_url}" # Check for inst.noverifyssl if grep -q inst.noverifyssl /proc/cmdline; then NOVERIFYSSL_WGET_OPT="--no-check-certificate" else NOVERIFYSSL_WGET_OPT="" fi declare -i cut_dirs=NUM_DIRS cd "${INSTALL_MOUNT}" mkdir -p logs mkdir -p Packages mkdir -p repodata feed_url=xxxHTTP_URLxxx # Fetch Packages wlog "${KS} Staged Install packages fetch from $feed_url/Packages" wget ${NOVERIFYSSL_WGET_OPT} --mirror --no-parent --no-host-directories --reject 'index.html*' --reject '*.log' \ --cut-dirs=$cut_dirs ${feed_url}/Packages/ -o ${INSTALL_MOUNT}/logs/rpmget.log \ || report_pre_failure_with_msg "Failed to fetch Packages ; see ${INSTALL_MOUNT}/logs/rpmget.log" wlog "${KS} Staged Packages to ${INSTALL_MOUNT}/Packages complete" # Fetch Repodata wlog "${KS} Staged Install repodata fetch from $feed_url/repodata" wget ${NOVERIFYSSL_WGET_OPT} --mirror --no-parent --no-host-directories --reject 'index.html*' --reject '*.log' \ --cut-dirs=$cut_dirs ${feed_url}/repodata/ -o ${INSTALL_MOUNT}/logs/rpmget_repo.log \ || report_pre_failure_with_msg "Failed to fetch repodata ; see ${INSTALL_MOUNT}/logs/rpmget_repo.log" wlog "${KS} Staged repodata to ${INSTALL_MOUNT}/repodata complete" # Fetch Patch Package Data quietly # - Patch Packages # - Patches repodata # - Patches metadata # - Save all patch packages to /opt/patching/packages/21.12 patches_url=xxxHTTP_URLxxx/patches wget ${NOVERIFYSSL_WGET_OPT} -q --spider ${patches_url}/ if [ $? -eq 0 ]; then wlog "${KS} Staged Install patch repository from $patches_url to ${INSTALL_MOUNT}/patches" mkdir -p ${INSTALL_MOUNT}/patches/Packages mkdir -p ${INSTALL_MOUNT}/patches/repodata cd ${INSTALL_MOUNT}/patches declare -i patches_cut_dirs=$((cut_dirs+1)) wlog "${KS} Staged Install fetch patch Packages from $patches_url/Packages" wget ${NOVERIFYSSL_WGET_OPT} --mirror --no-parent --no-host-directories --reject 'index.html*' \ --cut-dirs=$patches_cut_dirs $patches_url/Packages/ -o ${INSTALL_MOUNT}/logs/patches_rpmget.log \ || report_post_failure_with_logfile ${INSTALL_MOUNT}/logs/patches_rpmget.log wlog "${KS} Staged Install fetch patch repodata from $patches_url/repodata" wget ${NOVERIFYSSL_WGET_OPT} --mirror --no-parent --no-host-directories --reject 'index.html*' \ --cut-dirs=$patches_cut_dirs $patches_url/repodata/ -o ${INSTALL_MOUNT}/logs/patches_rpmget_repo.log \ || report_post_failure_with_logfile ${INSTALL_MOUNT}/logs/patches_rpmget_repo.log wlog "${KS} Staged Install fetch patch metadata from $patches_url/metadata" wget ${NOVERIFYSSL_WGET_OPT} --mirror --no-parent --no-host-directories --reject 'index.html*' \ --cut-dirs=$patches_cut_dirs $patches_url/metadata/ -o ${INSTALL_MOUNT}/logs/patches_rpmget_metadata.log \ || report_post_failure_with_logfile ${INSTALL_MOUNT}/logs/patches_rpmget_metadata.log wlog "${KS} Staged patches to ${INSTALL_MOUNT}/patches complete" else wlog "${KS} get from patches url '$patches_url' failed" fi cat << EOF > /tmp/repo-include repo --name=local-base --cost=100 --baseurl=file://${INSTALL_MOUNT}/ repo --name=local-updates --cost=100 --baseurl=file://${INSTALL_MOUNT}/patches/ repo --name=remote-base --cost=200 --baseurl=xxxHTTP_URLxxx/ repo --name=remote-updates --cost=200 --baseurl=xxxHTTP_URLxxx/patches/ EOF fi wlog "Using repo config:\n$(cat /tmp/repo-include)" %end # Repository arguments from %pre %include /tmp/repo-include %post --erroronfail # Source common functions . /tmp/ks-functions.sh KS="Miniboot post:" # wlog "${KS} cmdLine: $(cat /proc/cmdline)" if [ -e /dev/disk/by-label/oe_iso_boot ]; then # This is a hybrid ISO/network install. Mount the media to ensure Anaconda # ejects it on reboot. mkdir /mnt/iso wlog "${KS} mount for eject" mount /dev/disk/by-label/oe_iso_boot /mnt/iso else wlog "${KS} /dev/disk/by-label/oe_iso_boot does not exist" fi # persist the default http port number to platform configuration. This # will get overwritten when config_controller is run. echo http_port=8080 >> /etc/platform/platform.conf # Build networking scripts cat << EOF > /etc/sysconfig/network-scripts/ifcfg-lo DEVICE=lo IPADDR=127.0.0.1 NETMASK=255.0.0.0 NETWORK=127.0.0.0 BROADCAST=127.255.255.255 ONBOOT=yes IPV6_AUTOCONF=no NAME=loopback EOF %end %post --nochroot --erroronfail # Source common functions . /tmp/ks-functions.sh # Mirror local software repositories INSTALL_MOUNT=/mnt/install/repo SYSIMAGE_MOUNT=/mnt/sysimage FEED_DIR=${SYSIMAGE_MOUNT}/www/pages/feed/rel-21.12 UPDATES_DIR=${SYSIMAGE_MOUNT}/www/pages/updates/rel-21.12 PATCHING_DIR=${SYSIMAGE_MOUNT}/opt/patching PACKAGES_DIR=${PATCHING_DIR}/packages/21.12/ KS="Miniboot post:" need_patches=false # Handle 3 prestaging conditions # # 1. Full local install ; iso present in platform-backup/rel # 2. Prioritized install ; use prestaged content fetch what's missing remotely # 3. Staged install ; no prestaging content if [ -d /mnt/bootimage ]; then srcdir=/mnt/bootimage # Always need to fetch patches for Prestaged ISO install. # It is not sufficient to only get committed patches from the ISO, # There may also be non-committed patches applied to the system # controller that are needed as well. # Setting need_patches to true for the ISO install handles both commited # and non-committed patch cases. need_patches=true wlog "${KS} Local Install from $srcdir" elif [ -d ${INSTALL_MOUNT}/Packages ] ; then srcdir=${INSTALL_MOUNT} wlog "${KS} Staged Install from $srcdir" else srcdir=/mnt/platform-backup/21.12 wlog "${KS} looking for packages in ${srcdir}" fi # prepare to boot other hosts by mirroring sw repository if [ -d $srcdir/Packages ] ; then wlog "${KS} copying software repository $srcdir/Packages and $srcdir/repodata" mkdir -p ${FEED_DIR} if [ -d $srcdir/repodata ] ; then repodatafilecount=$(ls ${srcdir}/repodata | wc -l) if [ ${repodatafilecount} = 0 ]; then report_post_failure_with_msg "$srcdir/repodata files not found." else wlog "${KS} copying repodata from $srcdir/repodata to ${FEED_DIR}/repodata" cp -r $srcdir/repodata ${FEED_DIR}/repodata fi else report_post_failure_with_msg "$srcdir/repodata not found." fi packagesfilecount=$(ls ${srcdir}/Packages | wc -l) if [ ${packagesfilecount} = 0 ]; then report_post_failure_with_msg "$srcdir/Packages files not found." else wlog "${KS} copying packages from $srcdir/Packages to ${FEED_DIR}/Packages" cp -r $srcdir/Packages ${FEED_DIR}/Packages fi else report_post_failure_with_msg "$srcdir/Packages not found." fi if [ -d $srcdir/patches ]; then if [ -d $srcdir/patches/Packages ] ; then wlog "${KS} copying patch Packages from $srcdir/patches/Packages to ${UPDATES_DIR}/Packages" mkdir -p ${UPDATES_DIR} cp -r $srcdir/patches/Packages ${UPDATES_DIR}/Packages else wlog "${KS} $srcdir/patches/Packages doesn't exist. Fetching remotely" need_patches=true fi if [ -d $srcdir/patches/repodata ] ; then wlog "${KS} copying patch repodata from $srcdir/patches/repodata to ${UPDATES_DIR}/repodata" mkdir -p ${UPDATES_DIR} cp -r $srcdir/patches/repodata ${UPDATES_DIR}/repodata else wlog "${KS} $srcdir/patches/repodata doesn't exist. Fetching remotely" need_patches=true fi else wlog "${KS} $srcdir/patches doesn't exist. Fetching remotely" need_patches=true fi if [ -d $srcdir/patches/metadata -a "${need_patches}" = false ] ; then mkdir -p ${PATCHING_DIR} wlog "${KS} copying patch metadata from $srcdir/patches/metadata to ${PATCHING_DIR}/metadata" cp -r $srcdir/patches/metadata ${PATCHING_DIR}/metadata else wlog "${KS} $srcdir/patches/metadata doesn't exist. Fetching remotely" need_patches=true fi if [ -d $srcdir/patches -a "${need_patches}" = false ]; then mkdir -p ${PACKAGES_DIR} wlog "${KS} copying packages from ${UPDATES_DIR}/Packages to ${PACKAGES_DIR}" find ${UPDATES_DIR}/Packages -name '*.rpm' \ | xargs --no-run-if-empty -I files cp --preserve=all files ${PACKAGES_DIR} else wlog "${KS} $srcdir/patches doesn't exist: fetching remotely" need_patches=true fi if [ "${srcdir}" = "${INSTALL_MOUNT}" ] ; then # save the pre stage anaconda logs mkdir -p ${SYSIMAGE_MOUNT}/var/log/anaconda cp -a ${INSTALL_MOUNT}/logs/* ${SYSIMAGE_MOUNT}/var/log/anaconda fi if [ "${need_patches}" = true ]; then echo > ${SYSIMAGE_MOUNT}/tmp/needpatches fi true %end %post --erroronfail # Source common functions . /tmp/ks-functions.sh KS="Miniboot post:" FEED_DIR=/www/pages/feed/rel-21.12 # Create a uuid specific to this installation INSTALL_UUID=`uuidgen` echo $INSTALL_UUID > /www/pages/feed/rel-21.12/install_uuid echo "INSTALL_UUID=$INSTALL_UUID" >> /etc/platform/platform.conf wlog "${KS} updating platform.conf with install uuid : ${INSTALL_UUID}" # Mirror remote software repositories anaconda_logdir=/var/log/anaconda mkdir -p $anaconda_logdir # Check for inst.noverifyssl if grep -q inst.noverifyssl /proc/cmdline; then NOVERIFYSSL_WGET_OPT="--no-check-certificate" else NOVERIFYSSL_WGET_OPT="" fi # If the path to $FEED_DIR does not exist then proceed to create it and # fetch the ISO content in pieces from the system controller: # # - Packages # - Repodata # FEED_DIR=/www/pages/feed/rel-21.12 declare -i cut_dirs=NUM_DIRS declare need_patches= if [ -f /tmp/needpatches ]; then wlog "${KS} patches need to be downloaded" need_patches=true rm /tmp/needpatches else need_patches=false fi # Fetch Patch Package Data quietly # - Patch Packages # - Patches repodata # - Patches metadata # - Save all patch packages to /opt/patching/packages/21.12 patches_url=xxxHTTP_URLxxx/patches wget ${NOVERIFYSSL_WGET_OPT} -q --spider ${patches_url}/ if [ $? -eq 0 ] && [ "${need_patches}" = true ]; then wlog "${KS} downloading patch repository $patches_url" cd /www/pages mkdir -p updates/rel-21.12/Packages mkdir -p updates/rel-21.12/repodata cd updates/rel-21.12 declare -i patches_cut_dirs=$((cut_dirs+1)) this_dir=$(pwd) wlog "${KS} fetch patch packages from $patches_url/Packages to ${this_dir}" wget ${NOVERIFYSSL_WGET_OPT} --mirror --no-parent --no-host-directories --reject 'index.html*' \ --cut-dirs=$patches_cut_dirs $patches_url/Packages/ -o $anaconda_logdir/patches_rpmget.log \ || report_post_failure_with_logfile $anaconda_logdir/patches_rpmget.log wlog "${KS} fetch patch repodata from $patches_url/repodata to ${this_dir}" wget ${NOVERIFYSSL_WGET_OPT} --mirror --no-parent --no-host-directories --reject 'index.html*' \ --cut-dirs=$patches_cut_dirs $patches_url/repodata/ -o $anaconda_logdir/patches_rpmget_repo.log \ || report_post_failure_with_logfile $anaconda_logdir/patches_rpmget_repo.log mkdir -p /opt/patching/metadata mkdir -p /opt/patching/packages/21.12 cd /opt/patching wlog "${KS} fetch patch metadata from $patches_url/metadata to /opt/patching/metadata" wget ${NOVERIFYSSL_WGET_OPT} --mirror --no-parent --no-host-directories --reject 'index.html*' \ --cut-dirs=$patches_cut_dirs $patches_url/metadata/ -o $anaconda_logdir/patches_rpmget_metadata.log \ || report_post_failure_with_logfile $anaconda_logdir/patches_rpmget_metadata.log wlog "${KS} save a copy of all patch packages to /opt/patching/packages/21.12 ; preserve attributes" find /www/pages/updates/rel-21.12/Packages -name '*.rpm' \ | xargs --no-run-if-empty -I files cp --preserve=all files /opt/patching/packages/21.12/ else wlog "${KS} Patches are not required to be downloaded in post phase" fi %end