Added support for RedHat 8.x, redesign of the code

This commit is contained in:
malachma 2020-08-30 19:36:52 +02:00
Родитель 717f0aaa28
Коммит 4a26601715
4 изменённых файлов: 195 добавлений и 103 удалений

Просмотреть файл

@ -9,10 +9,10 @@
# Two partitions with one of it a LVM flagged one -> RedHAt with LVM
# Global redirection for ERR to STD
exec 2>&1
#exec 2>&1
# Declare array
a_part_info=()
declare -A a_part_info
# Functions
# ---------
@ -36,16 +36,19 @@ fsck_partition() {
# $2 holds the partiton info
Log-Info "File system check start"
if [[ "$1" == "xfs" ]]; then
Log-Info "fsck part $2"
xfs_repair -n "$2" > /dev/null 2>&1
elif [[ "$1" == "fat16" ]]; then
Log-Info "fsck part $2"
fsck.vfat -p "$2" > /dev/null 2>&1
else
Log-Info "fsck part $2"
fsck."$1" -p "$2" > /dev/null 2>&1
fi
if [[ "$?" == 4 ]]; then
# error 4 is returned by fsck.ext4 only
Log-Info "${root_rescue} is not able to be automatically recovered. Aborting ALAR"
Log-Info "Partition ${2} is not able to be automatically recovered. Aborting ALAR"
exit 1
fi
@ -62,18 +65,23 @@ fsck_partition() {
verifyRedHat() {
if [[ ! -d /tmp/assert ]]; then
mkdir /tmp/assert
mkdir /tmp/assert;
fi
if [[ "${isLVM}" == "true" ]]; then
Log-Info "Verifying LVM setup"
pvscan > /dev/null 2>&1
vgscan > /dev/null 2>&1
lvscan > /dev/null 2>&1
local fs=$(parted $(lvscan | grep rootlv | awk '{print $2}' | tr -d "'") print | grep -E '^ ?[0-9]{1,2} *' | awk '{print $5}')
root_part_fs=$(parted $(lvscan | grep rootlv | awk '{print $2}' | tr -d "'") print | grep -E '^ ?[0-9]{1,2} *' | awk '{print $5}')
# Set variable rescue_root to the right LV name
rescue_root=$(lvscan | grep rootlv | awk '{print $2}' | tr -d "'")
fsck_partition "${fs}" "${rescue_root}"
rescue_usr=$(lvscan | grep usrlv | awk '{print $2}' | tr -d "'")
fsck_partition "${root_part_fs}" "${rescue_root}"
# We can use the same FS type in this case
fsck_partition "${root_part_fs}" "${rescue_usr}"
mount $(lvscan | grep rootlv | awk '{print $2}' | tr -d "'") /tmp/assert
mount $(lvscan | grep usrlv | awk '{print $2}' | tr -d "'") /tmp/assert/usr
else
# The file system got globally defiend before
fsck_partition "${root_part_fs}" "${rescue_root}"
@ -83,6 +91,7 @@ verifyRedHat() {
if [[ -e /tmp/assert/etc/os-release ]]; then
PRETTY_NAME="$(grep PRETTY_NAME /tmp/assert/etc/os-release)"
PRETTY_NAME="${PRETTY_NAME##*=}"
echo "PRETTY NAME : ${PRETTY_NAME}"
case "${PRETTY_NAME}" in
*CentOS* | *Red\ Hat*)
isRedHat="true"
@ -105,15 +114,15 @@ verifyRedHat() {
fi
fi
# clean up
umount /tmp/assert/usr
umount /tmp/assert
rm -fr /tmp/assert
}
verifyUbuntu() {
if [[ ! -d /tmp/assert ]]; then
mkdir /tmp/assert
mkdir /tmp/assert;
fi
fsck_partition "${root_part_fs}" "${rescue_root}"
mount "${rescue_root}" /tmp/assert
if [[ -e /tmp/assert/etc/os-release ]]; then
PRETTY_NAME="$(grep PRETTY_NAME /tmp/assert/etc/os-release)"
@ -137,9 +146,8 @@ verifyUbuntu() {
verifySuse() {
if [[ ! -d /tmp/assert ]]; then
mkdir /tmp/assert
mkdir /tmp/assert;
fi
fsck_partition "${root_part_fs}" "${rescue_root}"
mount "$rescue_root" /tmp/assert
if [[ -e /tmp/assert/etc/os-release ]]; then
PRETTY_NAME="$(grep PRETTY_NAME /tmp/assert/etc/os-release)"
@ -164,19 +172,72 @@ verifySuse() {
# -----
# Get partition info/details
for i in $(sudo echo I | parted "$(readlink -f /dev/disk/azure/scsi1/lun0)" print | grep -E '^ ?[0-9]{1,2} *' | awk '{print $1 ":" $5 ":" $6 ":" $7 ":" $8 "$"}'); do
a_part_info+=($i)
done
#for i in $(echo I | parted /dev/sda print | grep -E '^ ?[0-9]{1,2} *' | awk '{print $1 ":" $5 ":" $6 ":" $7 ":" $8 "$"}'); do
#a_part_info+=($i)
#done
# parted -m /dev/sda print | grep -E '^ ?[0-9]{1,2} *' | cut -d ':' -f1,5,6,7
# 14:::bios_grub;
# 15:fat16:EFI System Partition:boot, esp;
# 1:xfs::;
# 2:::lvm;
# NAME="CentOS Linux"
# VERSION="8 (Core)"
# parted -m /dev/sda print | grep -E '^ ?[0-9]{1,2} *' | cut -d ':' -f1,5,6,7
# 14:::bios_grub;
# 15:fat16:EFI System Partition:boot;
# 1:ext4::;
# 2:::lvm;
# [root@alar-cent1 ~]# cat /etc/os-release
# NAME="CentOS Linux"
# VERSION="7 (Core)"
# parted -m /dev/sda print | grep -E '^ ?[0-9]{1,2} *' | cut -d ':' -f1,5,6,7
# 1:fat16:EFI System Partition:boot;
# 2:xfs::;
# 3:::bios_grub;
# 4:::lvm;
# [root@alar1 ~]# cat /etc/os-release
# NAME="Red Hat Enterprise Linux Server"
# VERSION="7.8 (Maipo)"
# parted -m /dev/sda print | grep -E '^ ?[0-9]{1,2} *' | cut -d ':' -f1,5,6,7
# 14:::bios_grub;
# 15:fat16:EFI System Partition:boot, esp;
# 1:xfs::;
# 2:::lvm;
# [root@alar2 ~]# cat /etc/os-release
# NAME="Red Hat Enterprise Linux"
# VERSION="8.2 (Ootpa)"
OLDIFS=$IFS
IFS=; # overwriting IFS to use the semicolon as a line seperator
j=0 # Needed as counter
while read _partition; do a_part_info[$j]=$_partition; let j++; done <<< $( parted -m "$(readlink -f /dev/disk/azure/scsi1/lun0)" print | grep -E '^ ?[0-9]{1,2} *')
IFS=$OLDIFS
getPartitionNumberDetail(){
# $1 key
local result
result=$(cut -d ':' -f1 <<< ${a_part_info[$1]})
echo $result
}
getPartitionFilesystemDetail(){
# $1 key
local result
result=$(cut -d ':' -f5 <<< ${a_part_info[$1]})
echo $result
}
# Old Ubuntu?
if [[ "${#a_part_info[@]}" -eq 1 ]]; then
Log-Info "This could be an old Ubuntu image"
root_part_number=$(for i in "${a_part_info[@]}"; do grep boot <<<"$i"; done | cut -d':' -f1)
root_part_fs=$(for i in "${a_part_info[@]}"; do grep boot <<<"$i"; done | cut -d':' -f3)
for k in ${!a_part_info[@]}; do
grep -q boot <<< ${a_part_info[$k]} && root_part_number=$(getPartitionNumberDetail $k) && root_part_fs=$(getPartitionFilesystemDetail $k);
done
rescue_root=$(readlink -f /dev/disk/azure/scsi1/lun0-part"${root_part_number}")
verifyUbuntu
@ -185,10 +246,16 @@ fi
# RedHat 6.x or 7.x?
if [[ "${#a_part_info[@]}" -eq 2 ]]; then
Log-Info "This could be a RedHat/Centos 6/7 image"
boot_part_number=$(for i in "${a_part_info[@]}"; do grep boot <<<"$i"; done | cut -d':' -f1)
boot_part_fs=$(for i in "${a_part_info[@]}"; do grep boot <<<"$i"; done | cut -d':' -f3)
root_part_number=$(for i in "${a_part_info[@]}"; do grep -v boot <<<"$i"; done | cut -d':' -f1)
root_part_fs=$(for i in "${a_part_info[@]}"; do grep -v boot <<<"$i"; done | cut -d':' -f3)
for k in ${!a_part_info[@]}; do
grep -q boot <<< ${a_part_info[$k]} && boot_part_number=$(getPartitionNumberDetail $k) && boot_part_fs=$(getPartitionFilesystemDetail $k);
grep -qv boot <<< ${a_part_info[$k]} && root_part_number=$(getPartitionNumberDetail $k) && root_part_fs=$(getPartitionFilesystemDetail $k);
done
# Check whether we have a LVM system.
for k in ${!a_part_info[@]}; do
grep -q lvm <<< ${a_part_info[$k]} && isLVM="true";
done
# RedHat 6.x does have ext4 filesystem
# Whereas RedHat 7.x does have the XFS filesystem
@ -198,17 +265,16 @@ if [[ "${#a_part_info[@]}" -eq 2 ]]; then
isXFS="true"
fi
# Check whether we have a LVM system.
if [[ "$root_part_fs" == "lvm" ]]; then
isLVM="true"
fi
# Set root_rescue and boot_part in order to mount the disk correct
# In case we have a LVM system we handle this in more detail in base.sh
rescue_root=$(readlink -f /dev/disk/azure/scsi1/lun0-part"${root_part_number}")
if [[ "$isLVM" == "false" ]]; then
fsck_partition "${root_part_fs}" "${root_part}"
fi
boot_part=$(readlink -f /dev/disk/azure/scsi1/lun0-part"${boot_part_number}")
fsck_partition "${boot_part_fs}" "${boot_part}"
verifyRedHat # In case we have LVM partitions after this point the variable "rescue_root" is overwritten with the correct value
verifyRedHat
fi
@ -221,41 +287,64 @@ if [[ "${#a_part_info[@]}" -eq 3 ]]; then
Log-Error "Freebsd is not a supported OS. ALAR tool is stopped"
osNotSupported="true"
else
boot_part_number=$(for i in "${a_part_info[@]}"; do grep boot <<<"$i"; done | cut -d':' -f1)
efi_part_number=$(for i in "${a_part_info[@]}"; do grep bios <<<"$i"; done | cut -d':' -f1)
root_part_number=$(for i in "${a_part_info[@]}"; do grep -v bios <<<"$i" | grep -v boot; done | cut -d':' -f1)
root_part_fs=$(for i in "${a_part_info[@]}"; do grep -v bios <<<"$i" | grep -v boot; done | cut -d':' -f2)
boot_part_fs=$(for i in "${a_part_info[@]}"; do grep -v boot <<<"$i"; done | cut -d':' -f2)
efi_part_fs=$(for i in "${a_part_info[@]}"; do grep -v bios <<<"$i"; done | cut -d':' -f2)
for k in ${!a_part_info[@]}; do
grep -q boot <<< ${a_part_info[$k]} && efi_part_number=$(getPartitionNumberDetail $k) && efi_part_fs=$(getPartitionFilesystemDetail $k);
grep -qv 'bios\|boot' <<< ${a_part_info[$k]} && root_part_number=$(getPartitionNumberDetail $k) && root_part_fs=$(getPartitionFilesystemDetail $k);
done
# Set root_rescue and boot_part in order to mount the disk correct
rescue_root=$(readlink -f /dev/disk/azure/scsi1/lun0-part"${root_part_number}")
boot_part=$(readlink -f /dev/disk/azure/scsi1/lun0-part"${boot_part_number}")
fsck_partition "${boot_part_fs}" "${boot_part}"
fsck_partition "${root_part_fs}" "${rescue_root}"
efi_part=$(readlink -f /dev/disk/azure/scsi1/lun0-part"${efi_part_number}")
isUbuntuEFI="true"
fsck_partition "${efi_part_fs}" "${efi_part}"
verifyUbuntu
fi
fi
#Suse 12 or 15?
if [[ "${#a_part_info[@]}" -eq 4 ]]; then
# Not sure whethe this is a RedHat or CENTOS with LVM or it is a Suse 12/15 instead
# Need to make a simple test
for k in ${!a_part_info[@]}; do
grep -s lxboot <<< ${a_part_info[$k]} && isSuseBoot=true;
done
if [[ "$isSuseBoot" == "true" ]]; then
#Suse 12 or 15?
Log-Info "This could be a SUSE 12 or 15 image"
# Get boot partition
boot_part_number=$(for i in "${a_part_info[@]}"; do grep lxboot <<<"$i"; done | cut -d':' -f1)
efi_part_number=$(for i in "${a_part_info[@]}"; do grep UEFI <<<"$i"; done | cut -d':' -f1)
root_part_number=$(for i in "${a_part_info[@]}"; do grep lxroot <<<"$i"; done | cut -d':' -f1)
root_part_fs=$(for i in "${a_part_info[@]}"; do grep lxroot <<<"$i"; done | cut -d':' -f2)
boot_part_fs=$(for i in "${a_part_info[@]}"; do grep lxboot <<<"$i"; done | cut -d':' -f2)
efi_part_fs=$(for i in "${a_part_info[@]}"; do grep UEFI <<<"$i"; done | cut -d':' -f2)
for k in ${!a_part_info[@]}; do
grep -q lxboot <<< ${a_part_info[$k]} && boot_part_number=$(getPartitionNumberDetail $k) && boot_part_fs=$(getPartitionFilesystemDetail $k);
grep -q UEFI <<< ${a_part_info[$k]} && efi_part_number=$(getPartitionNumberDetail $k) && efi_part_fs=$(getPartitionFilesystemDetail $k);
grep -q lxroot <<< ${a_part_info[$k]} && root_part_number=$(getPartitionNumberDetail $k) && root_part_fs=$(getPartitionFilesystemDetail $k);
done
# Set root_rescue and boot_part in order to mount the disk correct
rescue_root=$(readlink -f /dev/disk/azure/scsi1/lun0-part"${root_part_number}")
fsck_partition "${root_part_fs}" "${rescue_root}"
boot_part=$(readlink -f /dev/disk/azure/scsi1/lun0-part"${boot_part_number}")
fsck_partition "${boot_part_fs}" "${boot_part}"
efi_part=$(readlink -f /dev/disk/azure/scsi1/lun0-part"${efi_part_number}")
fsck_partition "${efi_part_fs}" "${efi_part}"
verifySuse
else
Log-Info "This is a recent RedHat or CentOS image with 4 partitions"
for k in ${!a_part_info[@]}; do
grep -q EFI <<< ${a_part_info[$k]} && efi_part_number=$(getPartitionNumberDetail $k) && efi_part_fs=$(getPartitionFilesystemDetail $k);
grep -v EFI <<< ${a_part_info[$k]} | grep -v lvm | grep -v bios && boot_part_number=$(getPartitionNumberDetail $k) && boot_part_fs=$(getPartitionFilesystemDetail $k);
grep -q lvm <<< ${a_part_info[$k]} && lvm_part_number=$(getPartitionNumberDetail $k);
done
# Those images are LVM based
isLVM="true"
# Not a RedHat 6.x system
isRedHat6="false"
boot_part=$(readlink -f /dev/disk/azure/scsi1/lun0-part"${boot_part_number}")
fsck_partition "${boot_part_fs}" "${boot_part}"
efi_part=$(readlink -f /dev/disk/azure/scsi1/lun0-part"${efi_part_number}")
fsck_partition "${efi_part_fs}" "${efi_part}"
verifyRedHat
fi
fi
# No standard image
@ -264,3 +353,5 @@ if [[ "${#a_part_info[@]}" -gt 4 ]]; then
osNotSupported="true"
fi
# DEBUG
# printenv

Просмотреть файл

@ -30,11 +30,17 @@ recover_redhat() {
awk -f alar-fki/grub.awk /boot/grub/grub.conf
# rebuild the initrd
dracut -f /boot/initramfs-"${kernel_version}".img "$kernel_version"
else
if [[ $(grep -qe 'VERSION_ID="8.[1-2]"' /etc/os-release) -eq 0 ]]; then
for installed_kernel in $(rpm -qa kernel); do
kernel-install add $(sed 's/kernel-//' <<< $installed_kernel) /lib/modules/$(sed 's/kernel-//' <<< $installed_kernel)/vmlinuz
done
else
depmod ${kernel_version}
mkinitrd --force /boot/initramfs-"${kernel_version}".img "$kernel_version"
grub2-mkconfig -o /boot/grub2/grub.cfg
fi
fi
}

Просмотреть файл

@ -7,16 +7,8 @@
set_grub_default() {
# if not set to saved, replace it
sed -i "s/GRUB_DEFAULT=[[:digit:]]/GRUB_DEFAULT=saved/" /etc/default/grub
echo GRUB_DISABLE_OS_PROBER=true >>/etc/default/grub
#GRUB_DEFAULT=saved
#GRUB_SAVEDEFAULT=true
}
# at first alter the grub configuration to set GRUB_DEFAULT=saved if needed
if [[ $isRedHat6 == "false" ]]; then
set_grub_default
fi
# set the default kernel accordingly
# This is different for RedHat and Ubuntu/SUSE distros
# Ubuntu and SLES use sub-menues
@ -24,20 +16,26 @@ fi
# the variables are defined in base.sh
if [[ $isRedHat == "true" ]]; then
if [[ $isRedHat6 == "true" ]]; then
sed -i 's/default=0/default=1/' /boot/grub/grub.conf
grubby --set-default=1 # This is the previous kernel
else
grub2-set-default 1 # This is the last previous kernel
grub2-mkconfig -o /boot/grub2/grub.cfg
set_grub_default
grubby --set-default=1 # This is the previous kernel
# Fix for a bug in RedHat 8.1/8.2
# This needs to be fixed as soon as the bug with grub2-mkconfig is solved too
# grub2-mkconfig must not be executed because of this bug
$(grep -qe 'VERSION_ID="8.[1-2]"' /etc/os-release) && $(sed -i 's/set default="0"/set default="${saved_entry}"/' grub.cfg)
fi
fi
if [[ $isUbuntu == "true" ]]; then
set_grub_default
sed -i -e 's/GRUB_DEFAULT=.*/GRUB_DEFAULT="1>2"/' /etc/default/grub
update-grub
fi
if [[ $isSuse == "true" ]]; then
#grub2-set-default "1>2"
set_grub_default
sed -i -e 's/GRUB_DEFAULT=.*/GRUB_DEFAULT="1>2"/' /etc/default/grub
grub2-mkconfig -o /boot/grub2/grub.cfg
fi

Просмотреть файл

@ -6,6 +6,7 @@ export isRedHat="false"
export isRedHat6="false"
export isSuse="false"
export isUbuntu="false"
export isUbuntuEFI="false"
export tmp_dir=""
export recover_action=""
export boot_part=""
@ -19,6 +20,7 @@ export osNotSupported="true" # set to true by default, gets changed to false if
export tmp_dir=""
export global_error="false"
export actions="fstab initrd kernel" # These are the basic actions at the moment
export root_part_fs # set in distro-test
# Functions START
# Define some helper functions
@ -42,6 +44,7 @@ recover_action() {
[[ ${global_error} == "true" ]] && return 11
}
isInAction() {
#be quiet, just let us know this action exists
grep -q "$1" <<<"$actions"
@ -49,8 +52,8 @@ isInAction() {
}
copyRecoverScriptsToTemp() {
cp -r ./src/linux/common/helpers/alar/* ${tmp_dir}
cp -r ./src/linux/common/* ${tmp_dir}
cp -Lr ./src/linux/common/helpers/alar/* ${tmp_dir}
cp -Lr ./src/linux/common/* ${tmp_dir}
mkdir -p ${tmp_dir}/src/linux/common
ln -s ${tmp_dir}/helpers ${tmp_dir}/src/linux/common/helpers
ln -s ${tmp_dir}/setup ${tmp_dir}/src/linux/common/setup
@ -90,12 +93,14 @@ else
exit 1
fi
#Mount the root part
#====================
# Prepare and mount the partitions. Take into account what distro we have to deal with
# At first we have to mount the root partion of the VM we need to recover
if [[ ! -d /mnt/rescue-root ]]; then
mkdir /mnt/rescue-root
fi
# At the moment we handle only LVM on RedHat/CentOS
if [[ ${isLVM} == "true" ]]; then
pvscan
vgscan
@ -106,15 +111,16 @@ if [[ ${isLVM} == "true" ]]; then
usrlv=$(lvscan | grep usrlv | awk '{print $2}' | tr -d "'")
varlv=$(lvscan | grep varlv | awk '{print $2}' | tr -d "'")
# ext4 i used together with LVM, so no further handling is required
# The mount tool is automatically able to handle other fs-types
mount ${rootlv} /mnt/rescue-root
mount ${tmplv} /mnt/rescue-root/tmp
mount ${optlv} /mnt/rescue-root/opt
#mount ${tmplv} /mnt/rescue-root/tmp
#mount ${optlv} /mnt/rescue-root/opt
mount ${usrlv} /mnt/rescue-root/usr
mount ${varlv} /mnt/rescue-root/var
# No LVM, thus do the normal mount steps
elif [[ "${isRedHat}" == "true" || "${isSuse}" == "true" ]]; then
# noouid is valid for XFS only
# The extra step is only performed to be sure we have no overlaps with any UUID on an XFS FS
if [[ "${isExt4}" == "true" ]]; then
mount -n "${rescue_root}" /mnt/rescue-root
elif [[ "${isXFS}" == "true" ]]; then
@ -122,21 +128,15 @@ elif [[ "${isRedHat}" == "true" || "${isSuse}" == "true" ]]; then
fi
fi
if [[ "$isUbuntu" == "true" ]]; then
mount -n "$rescue_root" /mnt/rescue-root
fi
#Mount the boot part
#===================
if [[ ! -d /mnt/rescue-root/boot ]]; then
mkdir /mnt/rescue-root/boot
fi
if [[ ${isLVM} == "true" ]]; then
boot_part_number=$(for i in "${a_part_info[@]}"; do grep boot <<<"$i"; done | cut -d':' -f1)
boot_part=$(readlink -f /dev/disk/azure/scsi1/lun0-part"${boot_part_number}")
mount ${boot_part} /mnt/rescue-root/boot
else
# Ubuntu does not have an extra boot partition
if [[ "$isRedHat" == "true" || "$isSuse" == "true" ]]; then
# noouid is valid for XFS only
if [[ "${isExt4}" == "true" || "${isExt3}" == "true" ]]; then
@ -145,16 +145,14 @@ else
mount -o nouuid "${boot_part}" /mnt/rescue-root/boot
fi
fi
fi
# Mount the EFI part if Suse
if [[ "${isSuse}" == "true" ]]; then
if [[ ! -d /mnt/rescue-root/boot/efi ]]; then
mkdir /mnt/rescue-root/boot/efi
fi
# EFI partitions are only able to be mounted after we have mounted the boot partition
if [[ -n "$efi_part" ]]; then
mount "${efi_part}" /mnt/rescue-root/boot/efi
fi
#Mount the support filesystems
#==============================
#see also http://linuxonazure.azurewebsites.net/linux-recovery-using-chroot-steps-to-recover-vms-that-are-not-accessible/
@ -205,23 +203,22 @@ for i in dev/pts proc tmp sys dev; do umount /mnt/rescue-root/"$i"; done
if [[ "$isUbuntu" == "true" || "$isSuse" == "true" ]]; then
#is this really needed for Suse?
umount /mnt/rescue-root/run
if [[ -d /mnt/rescue-root/boot/efi ]]; then
umount /mnt/rescue-root/boot/efi
fi
fi
if [[ "${isLVM}" == "true" ]]; then
umount /mnt/rescue-root/tmp
umount /mnt/rescue-root/opt
# umount /mnt/rescue-root/tmp
# umount /mnt/rescue-root/opt
umount /mnt/rescue-root/usr
umount /mnt/rescue-root/var
fi
[[ $(mountpoint -q /mnt/rescue_root/boot) -eq 0 ]] && umount /mnt/rescue-root/boot && rm -d /mnt/rescue-root/boot
if [[ -n "$efi_part" ]]; then
umount "${efi_part}"
fi
umount /mnt/rescue-root/boot
umount /mnt/rescue-root
rm -fr /mnt/rescue-root
rmdir /mnt/rescue-root
rm -fr "${tmp_dir}"
if [[ "${recover_status}" == "11" ]]; then