This commit is contained in:
malachma 2023-02-07 12:41:41 +01:00
Родитель ffa4f7f96f
Коммит 4f8d31927c
31 изменённых файлов: 0 добавлений и 3923 удалений

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

@ -1,49 +0,0 @@
# Azure Linux Auto Recover
The Azure Linux Auto Recover (ALAR) scripts
are intended to fix boot issue for the most common issues.
The most common scenarios which are covered at the moment are:
* malformed /etc/fstab
* syntax error
* missing disk
* damaged initrd or missing initrd line in the /boot/grub/grub.cfg
* last installed kernel is not bootable
### FSTAB
This script does strip off any lines in the /etc/fstab file which are not needed to boot a system
It makes a copy of the original file first. So after the start of the OS the admin is able to edit the fstab again and correct any errors which didnt allow a reboot of the system before
### Kernel
This script does change the default kernel.
It modifies the configuration so that the previous kernel version gets booted. After the boot the admin is able to replace the broken kernel.
### Initrd
This script corrects two issues that can happen when a new kernel gets installed
1. The grub.cfg file is missing an “initrd” line or is missing the file to be use
2. The initrd image is missing
So it either fixes the grub.cfg file and/or creates a new initrd image
### How can I recover my failed VM?
To use the ALAR scripts with the help of the vm repair extension you have to utilize the command run and its option --run-id
The script-id for the automated recovery is: linux-alar-fki
#### Example ####
az vm repair create --verbose -g centos7 -n cent7 --repair-username rescue --repair-password 'password!234
az vm repair run --verbose -g centos7 -n cent7 --run-id linux-alar-fki --parameters initrd --run-on-repair
az vm repair restore --verbose -g centos7 -n cent7
You can pass over either a single recover-operation or multiple operations, i.e., fstab; fstab,initrd
Separate the recover operation with a comma in this case – no spaces allowed!
### Limitation
* encrypted images are not supported
* Classic VMs are not supported
* EFI based images are not supported yet. It is work in progress

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

@ -1,344 +0,0 @@
#!/bin/bash
# Partition Rules
# ================
# One partition -> Ubuntu
# Two partitions -> Redhat 6.x, 7,x
# Tree partitions --> a recent Ubuntu 16.x or 18.x
# Four partitions -> Suse
# Two partitions with one of it a LVM flagged one -> RedHAt with LVM
# Global redirection for ERR to STD
#exec 2>&1
# Declare array
declare -A a_part_info
# Functions
# ---------
whatFs() {
case "${1}" in
ext4)
isExt4="true"
;;
ext3)
isExt3="true"
;;
xfs)
isXFS="true"
;;
esac
}
fsck_partition() {
# $1 holds the type of the filesystem we need to check
# $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 "Partition ${2} is not able to be automatically recovered. Aborting ALAR"
exit 1
fi
if [[ "${isXFS}" == "true" && "$?" == 1 ]]; then
# xfs_repair -n returns 1 if the fs is corrupted.
# Also fsck may raise this error but we ignore it as even a normal recover is raising it. FALSE-NEGATIVE
Log-Info "A general error occured while trying to recover the device ${root_rescue}. Aborting ALAR"
exit 1
fi
Log-Info "The error state/number is: $?"
Log-Info "File system check finished"
}
verifyRedHat() {
if [[ ! -d /tmp/assert ]]; then
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
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 "'")
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}"
mount "${rescue_root}" /tmp/assert
fi
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"
osNotSupported="false"
whatFs ${root_part_fs}
;;
esac
else
if [[ -e /tmp/assert/etc/redhat-release ]]; then
PRETTY_NAME="$(cat /tmp/assert//etc/redhat-release)"
PRETTY_NAME="${PRETTY_NAME##*=}"
case "${PRETTY_NAME}" in
*CentOS* | *Red\ Hat*)
isRedHat="true"
isRedHat6="true"
osNotSupported="false"
whatFs ${root_part_fs}
;;
esac
fi
fi
# clean up
umount /tmp/assert/usr
umount /tmp/assert
rm -fr /tmp/assert
}
verifyUbuntu() {
if [[ ! -d /tmp/assert ]]; then
mkdir /tmp/assert;
fi
mount "${rescue_root}" /tmp/assert
if [[ -e /tmp/assert/etc/os-release ]]; then
PRETTY_NAME="$(grep PRETTY_NAME /tmp/assert/etc/os-release)"
PRETTY_NAME="${PRETTY_NAME##*=}"
case "${PRETTY_NAME}" in
*Ubuntu*)
isUbuntu="true"
osNotSupported="false"
whatFs ${root_part_fs}
;;
*Debian*)
isUbuntu="true"
osNotSupported="false"
whatFs ${root_part_fs}
;;
esac
else
# We need this part as in rare occasions CentOS may come with one partition as well
if [[ -e /tmp/assert/etc/redhat-release ]]; then
# clean up
umount /tmp/assert
rm -fr /tmp/assert
verifyRedHat
else
isUbuntu="false"
osNotSupported="true"
whatFs ${root_part_fs}
fi
fi
# clean up
umount /tmp/assert
rm -fr /tmp/assert
}
verifySuse() {
if [[ ! -d /tmp/assert ]]; then
mkdir /tmp/assert;
fi
mount "$rescue_root" /tmp/assert
if [[ -e /tmp/assert/etc/os-release ]]; then
PRETTY_NAME="$(grep PRETTY_NAME /tmp/assert/etc/os-release)"
PRETTY_NAME="${PRETTY_NAME##*=}"
case "${PRETTY_NAME}" in
*SUSE*)
isSuse="true"
osNotSupported="false"
whatFs ${root_part_fs}
;;
esac
else
isSuse="false"
osNotSupported="true"
whatFs ${root_part_fs}
fi
# clean up
umount /tmp/assert
rm -fr /tmp/assert
}
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 or even an CentOS with one partition only"
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
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"
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
if [[ "$root_part_fs" == "ext4" ]]; then
isRedHat6="true"
else
isXFS="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
fi
# Recent Ubuntu?
if [[ "${#a_part_info[@]}" -eq 3 ]]; then
Log-Info "This could be a recent Ubuntu 16.x or 18.x image"
# Check whether we have a Freebsd image. They have three partitions as well but we do not support this OS
if [[ "${a_part_info[@]}" =~ "freebsd" ]]; then
Log-Error "Freebsd is not a supported OS. ALAR tool is stopped"
osNotSupported="true"
else
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}")
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
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"
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
# Further tests need to be performed as we can not be sure that OS does come with LVM
[[ -z ${lvm_part_number} ]] && isLVM="false" || isLVM="true"
# Not a RedHat 6.x system
isRedHat6="false"
if [[ ${isLVM} == "true" ]]; then
Log-Info "OS with LVM setup"
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}"
else
Log-Info "OS with no LVM setup"
efi_part=$(readlink -f /dev/disk/azure/scsi1/lun0-part"${efi_part_number}")
fsck_partition "${efi_part_fs}" "${efi_part}"
# we can use hardcoded values
boot_part=$(readlink -f /dev/disk/azure/scsi1/lun0-part1)
fsck_partition "xfs" "${boot_part}"
rescue_root=$(readlink -f /dev/disk/azure/scsi1/lun0-part2)
root_part_fs="xfs"
fi
verifyRedHat
fi
fi
# No standard image
if [[ "${#a_part_info[@]}" -gt 4 ]]; then
Log-Error "Unrecognized Linux distribution. ALAR tool is stopped"
osNotSupported="true"
fi
# DEBUG
# printenv

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

@ -1,22 +0,0 @@
#!/bin/bash
cd ${tmp_dir}
. ./src/linux/common/setup/init.sh
mv -f /etc/fstab{,.copy}
# For Debian we need to instal gawk first. It comes only with mawk
apt install -y gawk
awk '/[[:space:]]+\/[[:space:]]+/ {print}' /etc/fstab.copy >>/etc/fstab
awk '/[[:space:]]+\/boot[[:space:]]+/ {print}' /etc/fstab.copy >>/etc/fstab
# For Suse
awk '/[[:space:]]+\/boot\/efi[[:space:]]+/ {print}' /etc/fstab.copy >>/etc/fstab
# In case we have a LVM system
awk '/rootvg-homelv/ {print}' /etc/fstab.copy >>/etc/fstab
awk '/rootvg-optlv/ {print}' /etc/fstab.copy >>/etc/fstab
awk '/rootvg-tmplv/ {print}' /etc/fstab.copy >>/etc/fstab
awk '/rootvg-usrlv/ {print}' /etc/fstab.copy >>/etc/fstab
awk '/rootvg-varlv/ {print}' /etc/fstab.copy >>/etc/fstab
cat /etc/fstab
Log-Info "Renaming original file /etc/fstab to /etc/fstab.copy"
Log-Info "Creating new /etc/fstab file with only /boot and / partitions."
Log-Info "This ensures we have a bootable system"

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

@ -1,75 +0,0 @@
#!/bin/awk
#
# this file is needed for RedHat 6.x distros. The grub.conf file is not regenerated by any tool
# compared to grub2. this is solved with the help of AWK and SED
# All modifications are only related to initrd. As this line is missing quite often after a kernel update
#
BEGIN {
i=0
kernel_version=""
}
$0 ~ /kernel|initrd/ && $0 !~ /^#|.*#/{
grub_directive[i]=$1
directive_value[i]=$2
indexLine[i]=NR
i++
}
#
# Build a substring delimited by '-' but start at the second character
#
#
function substr_c2(_i) {
return substr(directive_value[_i],index(directive_value[_i],"-")+1)
}
#
# Find out whether the grub directive follow the right order or whether we have one missing (initrd)
# In that case we need to know the number of the lines in order to insert an initrd line
#
function directiveMissing() {
k=0
for (j=0; j<i; j++) {
k = j
if ( grub_directive[k] == grub_directive[k+1] ) {
sed_modify="sed -e '" indexLine[k] "ainitrd /initramfs-" substr_c2(k) ".img' /boot/grub/grub.conf"
system(sed_modify)
kernel_version = substr_c2(k)
}
j++
}
}
#
# Find out whether the grub directiveValues for initrd is available
# If it is empty the right value has to be inserted
#
function directiveValueMissing() {
k=0
for (j=0; j<i; j++) {
k = j
if ( length(directive_value[k]) == 0 ) {
sed_modify="sed -e '" indexLine[k] "c\tinitrd /initramfs-" substr_c2(k-1) ".img' /boot/grub/grub.conf"
system(sed_modify)
kernel_version = substr_c2(k-1)
}
}
}
END {
directiveMissing()
directiveValueMissing()
print "Starting recreate of initramfs"
img_str="dracut -f /boot/initramfs-" substr_c2(0) ".img " substr_c2(0)
system(img_str)
print "Recreate of initramfs finished"
}

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

@ -1,72 +0,0 @@
#!/bin/bash
cd ${tmp_dir}
. ./src/linux/common/setup/init.sh
#
# recover logic for handling and initrd or kernel problem
#
recover_suse() {
kernel_type=$(uname -r | grep -q default && echo "kernel-default" || echo "kernel-azure")
kernel_version=$(zypper se -is ${kernel_type} | grep ${kernel_type} | awk '{print $7;exit}')
kernel_version=$(sed -e "s/kernel-//" <<< $(rpm -q kernel --last | head -n 1 | cut -f1 -d' '))
mkinitrd /boot/initrd-"${kernel_version}" "$kernel_version"
grub2-mkconfig -o /boot/grub2/grub.cfg
# Added for Suse 15
zypper install -y shim
/usr/sbin/shim-install --config-file=/boot/grub2/grub.cfg
}
recover_ubuntu() {
if [[ ! -e /var/log/dpkg.log ]]; then
# if this file is empty we have to assume that we have a vanilla system. Only one kernel available
kernel_version=$(ls /boot/vmlinuz-*)
kernel_version=${kernel_version#/boot/vmlinuz-}
else
kernel_version=$( zgrep linux-image /var/log/dpkg.log* | grep installed | cut -d' ' -f5 | cut -d':' -f1 | sed -e 's/linux-image-//' | grep ^[1-9] | sort -V | tail -n 1)
fi
# This is needed on Debian only
if [[ -e /boot/initrd.img-${kernel_version} ]]; then
rm /boot/initrd.img-${kernel_version}
fi
update-initramfs -k "$kernel_version" -c
update-grub
}
#
# Should handle all redhat based distros
#
recover_redhat() {
kernel_version=$(sed -e "s/kernel-//" <<< $(rpm -q kernel --last | head -n 1 | cut -f1 -d' '))
if [[ "$isRedHat6" == "true" ]]; then
# verify the grub.conf and correct it if needed
cd "$tmp_dir"
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.\?[0-2]\?\"' /etc/os-release) -eq 0 ]]; then
for installed_kernel in $(rpm -qa kernel); do
kernel-install add $(sed 's/kernel-//' <<< $installed_kernel) /boot/vmlinuz-$(sed 's/kernel-//' <<< $installed_kernel)
done
else
depmod ${kernel_version}
mkinitrd --force /boot/initramfs-"${kernel_version}".img "$kernel_version"
grub2-mkconfig -o /boot/grub2/grub.cfg
fi
fi
}
if [[ "$isRedHat" == "true" ]]; then
recover_redhat
fi
if [[ "$isSuse" == "true" ]]; then
recover_suse
fi
if [[ "$isUbuntu" == "true" ]]; then
recover_ubuntu
fi

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

@ -1,92 +0,0 @@
#!/bin/bash
# The main intention is to roll back to the previous working kernel
# We do this by altering the grub configuration
# From the man page
# Set the default boot menu entry for GRUB. This requires setting GRUB_DEFAULT=saved in /etc/default/grub
set_grub_default() {
# if not set to saved, replace it
sed -i "s/GRUB_DEFAULT=[[:digit:]]/GRUB_DEFAULT=saved/" /etc/default/grub
}
# set the default kernel accordingly
# This is different for RedHat and Ubuntu/SUSE distros
# Ubuntu and SLES use sub-menues
# the variables are defined in base.sh
if [[ $isRedHat == "true" ]]; then
if [[ $isRedHat6 == "true" ]]; then
grubby --set-default=1 # This is the previous kernel
ldconfig
else
set_grub_default
grubby --set-default=1 # This is the previous kernel
if [[ $(grep -qe 'VERSION_ID=\"7.\?[1-9]\?\"' /etc/os-release) ]]; then
grub2-mkconfig -o /boot/grub2/grub.cfg
fi
# Exception for RedHat 8.0 i.e sku RedHat:RHEL-HA:8.0:8.0.2020021914
# here we don't have to run the patch operation
if [[ $(grep -qe 'VERSION_ID="8\.0"' /etc/os-release) -eq 0 ]]; then
grub2-mkconfig -o /boot/grub2/grub.cfg
fi
# Fix for a bug in RedHat 8.1/8.2
# https://bugzilla.redhat.com/show_bug.cgi?id=1850193
# This needs to be fixed as soon as the bug with grub2-mkconfig is solved too
if [[ ($(grep -qe 'ID="rhel"' /etc/os-release) -eq 0) && ($(grep -qe 'VERSION_ID=\"8.\?[1-2]\?\"' /etc/os-release) -eq 0) ]]; then
# no bug with UEFI
if [[ -d /sys/firmware/efi ]]; then
grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg
else
cat > /boot/grub2/grub-cfg.patch <<EOF
11,12c
if [ -f (hd0,gpt15)/efi/redhat/grubenv ]; then
load_env -f (hd0,gpt15)/efi/redhat/grubenv
.
EOF
grub2-mkconfig -o /boot/grub2/grub.cfg
# Need to handle the condition where grubenv is a softlink
# This needs to be fixed if the new grub2 for redhat is available --> https://bugzilla.redhat.com/show_bug.cgi?id=1850193
if [[ -L /boot/grub2/grubenv ]]; then
yum install -y patch
patch /boot/grub2/grub.cfg /boot/grub2/grub-cfg.patch
fi
# These lines are required as we have the ld.so.cache not build correct
# Otherwise this can lead in no functional network afterwards
# TODO find a better solution and the root cause for it
mv /sbin/dhclient /sbin/dhclient.org
cat > /sbin/dhclient <<EOF
#!/bin/bash
# This script got created by linux-alar-fki
# in order to fix an ld.so.cache issue that does the dhclient not to work properly
ldconfig
/sbin/dhclient.org
EOF
chmod 755 /sbin/dhclient
fi
fi
fi
# enable sysreq
echo "kernel.sysrq = 1" >> /etc/sysctl.conf
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
set_grub_default
sed -i -e 's/GRUB_DEFAULT=.*/GRUB_DEFAULT="1>2"/' /etc/default/grub
grub2-mkconfig -o /boot/grub2/grub.cfg
fi
# For reference --> https://www.linuxsecrets.com/2815-grub2-submenu-change-boot-order

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

@ -1,236 +0,0 @@
#!/bin/bash
# Variables
#export UBUNTU_DISTRO="true"
export isRedHat="false"
export isRedHat6="false"
export isSuse="false"
export isUbuntu="false"
export isUbuntuEFI="false"
export tmp_dir=""
export recover_action=""
export boot_part=""
export rescue_root=""
export isExt4="false"
export isExt3="false"
export isXFS="false"
export isLVM="false"
export efi_part=""
export osNotSupported="true" # set to true by default, gets changed to false if this is the case
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
export LVM_SUPPRESS_FD_WARNINGS=1
# Functions START
# Define some helper functions
. ./src/linux/common/setup/init.sh
recover_action() {
cd "${tmp_dir}"
local recover_action=$1
if [[ -f "${tmp_dir}/alar-fki/${recover_action}.sh" ]]; then
Log-Info "Starting recover action: ${recover_action}"
chmod 700 "${tmp_dir}/alar-fki/${recover_action}.sh"
chroot /mnt/rescue-root "${tmp_dir}/alar-fki/${recover_action}.sh"
Log-Info "Recover action: ${recover_action} finished"
else
Log-Error "File ${recover_action}.sh does not exist. Exiting ALAR"
global_error="true"
fi
[[ ${global_error} == "true" ]] && return 11
}
isInAction() {
#be quiet, just let us know this action exists
grep -q "$1" <<<"$actions"
return "$?"
}
copyRecoverScriptsToTemp() {
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
}
# Funtions END
#
# Start of the script
#
# Create tmp dir in order to store our files we download
tmp_dir="$(mktemp -d)"
copyRecoverScriptsToTemp
cd "${tmp_dir}"
# Filename for the distro verification
distro_test="distro-test.sh"
# Global redirection for ERR to STD
exec 2>&1
#
# What OS we need to recover?
#
if [[ -f "$tmp_dir/alar-fki/${distro_test}" ]]; then
chmod 700 "${tmp_dir}/alar-fki/${distro_test}"
. "${tmp_dir}/alar-fki/${distro_test}" # invoke the distro test
# Do we have identifed a supported distro?
if [[ ${osNotSupported} == "true" ]]; then
Log-Error " Your OS can not be determined. The OS distros supported are"
Log-Error " CentOS/Redhat 6.8 - 8.2"
Log-Error " Ubuntu 16.4 LTS and Ubuntu 18.4 LTS"
Log-Error " Suse 12 and 15"
Log-Error " Debain 9 and 10"
Log-Error " ALAR will stop!"
Log-Error " If your OS is in the above list please report this issue at https://github.com/azure/repair-script-library/issues"
exit 1
fi
else
Log-Error "File ${distro_test}.sh could not be fetched. Exiting"
exit 1
fi
# 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
lvscan
rootlv=$(lvscan | grep rootlv | awk '{print $2}' | tr -d "'")
tmplv=$(lvscan | grep tmplv | awk '{print $2}' | tr -d "'")
optlv=$(lvscan | grep optlv | awk '{print $2}' | tr -d "'")
usrlv=$(lvscan | grep usrlv | awk '{print $2}' | tr -d "'")
varlv=$(lvscan | grep varlv | awk '{print $2}' | tr -d "'")
# 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 ${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
mount -n -o nouuid "${rescue_root}" /mnt/rescue-root
fi
fi
if [[ "$isUbuntu" == "true" ]]; then
mount -n "$rescue_root" /mnt/rescue-root
fi
#Mount the boot part
#===================
# 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
mount "${boot_part}" /mnt/rescue-root/boot
elif [[ "${isXFS}" == "true" ]]; then
mount -o nouuid "${boot_part}" /mnt/rescue-root/boot
fi
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/
for i in dev proc sys tmp dev/pts; do
if [[ ! -d /mnt/rescue-root/"$i" ]]; then
mkdir /mnt/rescue-root/"$i"
fi
mount -o bind /"$i" /mnt/rescue-root/"$i"
done
if [[ "${isUbuntu}" == "true" || "${isSuse}" == "true" ]]; then
if [[ ! -d /mnt/rescue-root/run ]]; then
mkdir /mnt/rescue-root/run
fi
mount -o bind /run /mnt/rescue-root/run
fi
# Reformat the action value
action_value=$(echo $1 | tr ',' ' ')
recover_status=""
# What action has to be performed now?
for k in $action_value; do
if [[ $(isInAction $k) -eq 0 ]]; then
case "${k,,}" in
fstab)
Log-Info "We have fstab as option"
recover_action "$k"
recover_status=0
;;
kernel)
Log-Info "We have kernel as option"
recover_action "$k"
recover_status=0
;;
initrd)
Log-Info "We have initrd as option"
recover_action "$k"
recover_status=0
;;
esac
fi
done
#Clean up everything
cd /
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
fi
if [[ "${isLVM}" == "true" ]]; then
# umount /mnt/rescue-root/tmp
# umount /mnt/rescue-root/opt
umount /mnt/rescue-root/usr
umount /mnt/rescue-root/var
fi
if [[ -n "$efi_part" ]]; then
umount "${efi_part}"
fi
umount /mnt/rescue-root/boot
umount /mnt/rescue-root
rmdir /mnt/rescue-root
rm -fr "${tmp_dir}"
if [[ "${recover_status}" == "11" ]]; then
Log-Error "The recover action throwed an error"
exit $STATUS_ERROR
else
exit $STATUS_SUCCESS
fi

587
src/linux/common/helpers/alar2/Cargo.lock сгенерированный
Просмотреть файл

@ -1,587 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "aho-corasick"
version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
dependencies = [
"memchr",
]
[[package]]
name = "alar2"
version = "0.3.0"
dependencies = [
"chrono",
"clap",
"cmd_lib",
"fs_extra",
"sys-mount",
"uapi",
]
[[package]]
name = "ansi_term"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
dependencies = [
"winapi",
]
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "bindgen"
version = "0.58.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f8523b410d7187a43085e7e064416ea32ded16bd0a4e6fc025e21616d01258f"
dependencies = [
"bitflags",
"cexpr",
"clang-sys",
"clap",
"env_logger",
"lazy_static",
"lazycell",
"log",
"peeking_take_while",
"proc-macro2",
"quote",
"regex",
"rustc-hash",
"shlex",
"which",
]
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "cc"
version = "1.0.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee"
[[package]]
name = "cexpr"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27"
dependencies = [
"nom",
]
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
dependencies = [
"libc",
"num-integer",
"num-traits",
"time",
"winapi",
]
[[package]]
name = "clang-sys"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa66045b9cb23c2e9c1520732030608b02ee07e5cfaa5a521ec15ded7fa24c90"
dependencies = [
"glob",
"libc",
"libloading",
]
[[package]]
name = "clap"
version = "2.33.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
dependencies = [
"ansi_term",
"atty",
"bitflags",
"strsim",
"textwrap",
"unicode-width",
"vec_map",
]
[[package]]
name = "cmd_lib"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ba0f413777386d37f85afa5242f277a7b461905254c1af3c339d4af06800f62"
dependencies = [
"cmd_lib_macros",
"faccess",
"lazy_static",
"log",
"os_pipe",
]
[[package]]
name = "cmd_lib_macros"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e66605092ff6c6e37e0246601ae6c3f62dc1880e0599359b5f303497c112dc0"
dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "env_logger"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3"
dependencies = [
"atty",
"humantime",
"log",
"regex",
"termcolor",
]
[[package]]
name = "errno"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa68f2fb9cae9d37c9b2b3584aba698a2e97f72d7aef7b9f7aa71d8b54ce46fe"
dependencies = [
"errno-dragonfly",
"libc",
"winapi",
]
[[package]]
name = "errno-dragonfly"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14ca354e36190500e1e1fb267c647932382b54053c50b14970856c0b00a35067"
dependencies = [
"gcc",
"libc",
]
[[package]]
name = "faccess"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e039175679baf763ddddf4f76900b92d4dae9411ee88cf42d2f11b976b09e07c"
dependencies = [
"bitflags",
"libc",
"winapi",
]
[[package]]
name = "fs_extra"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394"
[[package]]
name = "gcc"
version = "0.3.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
[[package]]
name = "glob"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
[[package]]
name = "hermit-abi"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8"
dependencies = [
"libc",
]
[[package]]
name = "humantime"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lazycell"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
version = "0.2.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614"
[[package]]
name = "libloading"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afe203d669ec979b7128619bae5a63b7b42e9203c1b29146079ee05e2f604b52"
dependencies = [
"cfg-if 1.0.0",
"winapi",
]
[[package]]
name = "log"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "loopdev"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94c0ef06b33e606cc9d0cb38d8f4cda8c313a3d182c80a830d39aab1762d8b9a"
dependencies = [
"bindgen",
"errno",
"libc",
]
[[package]]
name = "memchr"
version = "2.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
[[package]]
name = "nom"
version = "5.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
dependencies = [
"memchr",
"version_check",
]
[[package]]
name = "num-integer"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3"
[[package]]
name = "os_pipe"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb233f06c2307e1f5ce2ecad9f8121cffbbee2c95428f44ea85222e460d0d213"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "peeking_take_while"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check",
]
[[package]]
name = "proc-macro2"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
dependencies = [
"proc-macro2",
]
[[package]]
name = "regex"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
"thread_local",
]
[[package]]
name = "regex-syntax"
version = "0.6.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581"
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "shlex"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
[[package]]
name = "strsim"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "syn"
version = "1.0.62"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "123a78a3596b24fee53a6464ce52d8ecbf62241e6294c7e7fe12086cd161f512"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "sys-mount"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "777948089ea2ab5673e2062ff9818dd8ea9db04941f0ea9ab408b855858cc715"
dependencies = [
"bitflags",
"libc",
"loopdev",
]
[[package]]
name = "termcolor"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
dependencies = [
"winapi-util",
]
[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
dependencies = [
"unicode-width",
]
[[package]]
name = "thread_local"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd"
dependencies = [
"once_cell",
]
[[package]]
name = "time"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
dependencies = [
"libc",
"wasi",
"winapi",
]
[[package]]
name = "uapi"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c72d8c426678584cd311d3b8e9538778fd7d024de641b440850e458d50621fd"
dependencies = [
"cc",
"cfg-if 0.1.10",
"libc",
"uapi-proc",
]
[[package]]
name = "uapi-proc"
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16121f38f4afe754d6726ed388f1fb3e669c4594a3d29e1bdab1e795a450921f"
dependencies = [
"lazy_static",
"libc",
"proc-macro2",
"quote",
"regex",
"syn",
]
[[package]]
name = "unicode-width"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
[[package]]
name = "unicode-xid"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "vec_map"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]]
name = "version_check"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
[[package]]
name = "wasi"
version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
[[package]]
name = "which"
version = "3.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724"
dependencies = [
"libc",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
"winapi",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

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

@ -1,16 +0,0 @@
[package]
name = "alar2"
version = "0.3.1"
authors = ["malachma <malachma@microsoft.com>"]
edition = "2018"
license = "MIT"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
chrono = "0.4"
sys-mount = "1.3.0"
cmd_lib = "1.3.0"
fs_extra = "1.2.0"
clap = "2.33.3"
uapi = "0.2"

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

@ -1,56 +0,0 @@
# Azure Linux Auto Recover v2
The Azure Linux Auto Recover v2 (ALAR2) tool is intended to fix boot issue for the most common issues. ALAR2 superceeds the previous version. ALAR2 is completely rewritten in Rust. It provides also a standalone mode to run the tool without the help of the 'vm repair extension'.o
The most common scenarios which are covered at the moment are:
* malformed /etc/fstab
* syntax error
* missing disk
* damaged initrd or missing initrd line in the /boot/grub/grub.cfg
* last installed kernel is not bootable
* serialconsole and grub are not configured well
### FSTAB
This action does strip off any lines in the /etc/fstab file which are not needed to boot a system
It makes a copy of the original file first. So after the start of the OS the admin is able to edit the fstab again and correct any errors which didnt allow a reboot of the system before
### Kernel
This action does change the default kernel.
It modifies the configuration so that the previous kernel version gets booted. After the boot the admin is able to replace the broken kernel.
### Initrd
This action corrects two issues that can happen when a new kernel gets installed
1. The grub.cfg file is missing an “initrd” line or is missing the file to be use
2. The initrd image is missing
So it either fixes the grub.cfg file and/or creates a new initrd image
### Serialconsole
This action corrects and incorrect or malformed serialsconsole configuration as well
corrects an incorrect or malformed GRUB console configuration. With this option one gets information displayed on the serialconsole and gets also access to the GRUB menu in case it is not displaed because of an incorrect setup.
### How can I recover my failed VM?
To use the ALAR2 tool with the help of the vm repair extension you have to utilize the command run and its option --run-id
The script-id for the automated recovery is: linux-alar2
#### Example ####
az vm repair create --verbose -g centos7 -n cent7 --repair-username rescue --repair-password 'password!234 --copy-disk-name repairdiskcopy'
az vm repair run --verbose -g centos7 -n cent7 --run-id linux-alar2 --parameters initrd --run-on-repair
az vm repair restore --verbose -g centos7 -n cent7
You can pass over either a single recover-operation or multiple operations, i.e., fstab; fstab,initrd
Separate the recover operation with a comma in this case – no spaces allowed!
### Limitation
* Classic VMs are not supported
### Distributions supported
* CentOS/Redhat 6.8 - 8.2
* Ubuntu 16.4 LTS and Ubuntu 18.4 LTS
* Suse 12 and 15
* Debain 9 and 10

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

@ -1,19 +0,0 @@
20022-02-17 Marcus Lachmanez <malachma@microsoft.com>
* version changed to 0.3.1
* fixed the issue (https://github.com/Azure/repair-script-library/issues/29)
Ubuntu distro or RedHat/CentOS distros yre recognized correct
previous kernel version is set correct. Workarounds for 8.1 or 8.2 removed
20022-01-17 Marcus Lachmanez <malachma@microsoft.com>
* version changed to 0.3
* fixed an issue with identifying RedHat images
Reuired to identify the partitions with the help of sgdisk
* action-scripts do have access to the following ne environment variables
isADE : bool
root_part_path : string
efi_part_path : string
boot_part_path : string
isLVM : bool
lvm_root_part : string
lvm_usr_part : string
lvm_lvm_part : string
* pre-build binary available. No build on the recovery VM required.

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

@ -1,116 +0,0 @@
use crate::{constants, distro, helper};
use distro::DistroKind;
use std::io::Write;
use std::{env, fs, io, process};
pub(crate) fn run_repair_script(distro: &distro::Distro, action_name: &str) -> io::Result<()> {
helper::log_info("----- Start action -----");
// At first make the script executable
uapi::chmod(
format!("{}/{}-impl.sh", constants::ACTION_IMPL_DIR, action_name),
uapi::c::S_IXUSR | uapi::c::S_IRUSR,
)?;
//if let Err(e) = cmd_lib::run_fun!(chmod 700 /tmp/action_implementation/${action_name}-impl.sh) {
// helper::log_error(format!("Setting the execute permission bit failed! {}",e).as_str());
//}
match env::set_current_dir(constants::RESCUE_ROOT) {
Ok(_) => {}
Err(e) => println!("Error in set current dir : {}", e),
}
// Set the environment correct
let convert_bool = |state: bool| -> String {
if state {
"true".to_string()
} else {
"false".to_string()
}
};
match distro.kind {
DistroKind::Debian | DistroKind::Ubuntu => {
env::set_var("isUbuntu", "true");
env::set_var("isADE", convert_bool(distro.is_ade));
env::set_var("root_part_path", distro.rescue_root.root_part_path.as_str());
env::set_var("efi_part_path", helper::get_efi_part_path(distro).as_str());
env::set_var("boot_part_path", distro.boot_part.boot_part_path.as_str());
env::remove_var("isSuse");
env::remove_var("isRedHat");
env::remove_var("isRedHat6");
}
DistroKind::Suse => {
env::set_var("isSuse", "true");
env::set_var("root_part_path", distro.rescue_root.root_part_path.as_str());
env::set_var("efi_part_path", helper::get_efi_part_path(distro).as_str());
env::set_var("boot_part_path", distro.boot_part.boot_part_path.as_str());
env::remove_var("isUbuntu");
env::remove_var("isRedHat");
env::remove_var("isRedHat6");
}
DistroKind::RedHatCentOS => {
env::set_var("isRedHat", "true");
env::set_var("isADE", convert_bool(distro.is_ade));
env::set_var("root_part_path", distro.rescue_root.root_part_path.as_str());
env::set_var("efi_part_path", helper::get_efi_part_path(distro).as_str());
env::set_var("boot_part_path", distro.boot_part.boot_part_path.as_str());
match distro.is_lvm {
true => env::set_var("isLVM", "true"),
false => env::set_var("isLVM", "false"),
}
env::set_var("lvm_root_part", distro.lvm_details.lvm_root_part.as_str());
env::set_var("lvm_usr_part", distro.lvm_details.lvm_usr_part.as_str());
env::set_var("lvm_lvm_part", distro.lvm_details.lvm_var_part.as_str());
env::remove_var("isUbuntu");
env::remove_var("isSuse");
env::remove_var("isRedHat6");
}
DistroKind::RedHatCentOS6 => {
env::set_var("isRedHat", "true");
env::set_var("isADE", convert_bool(distro.is_ade));
env::set_var("isRedHat6", "true");
env::set_var("root_part_path", distro.rescue_root.root_part_path.as_str());
env::set_var("efi_part_path", helper::get_efi_part_path(distro).as_str());
env::set_var("boot_part_path", distro.boot_part.boot_part_path.as_str());
match distro.is_lvm {
true => env::set_var("isLVM", "true"),
false => env::set_var("isLVM", "false"),
}
env::set_var("lvm_root_part", distro.lvm_details.lvm_root_part.as_str());
env::set_var("lvm_usr_part", distro.lvm_details.lvm_usr_part.as_str());
env::set_var("lvm_lvm_part", distro.lvm_details.lvm_var_part.as_str());
env::remove_var("isUbuntu");
env::remove_var("isSuse");
}
DistroKind::Undefined => {} // Nothing to do
}
// Execute the action script
let output = process::Command::new("chroot")
.arg(constants::RESCUE_ROOT)
.arg("/bin/bash")
.arg("-c")
.arg(format!(
"{}/{}-impl.sh",
constants::ACTION_IMPL_DIR,
action_name
))
.output()?;
io::stdout().write_all(&output.stdout).unwrap();
helper::log_info("----- Action stopped -----");
Ok(())
}
pub(crate) fn is_action_available(action_name: &str) -> io::Result<bool> {
let dircontent = fs::read_dir(constants::ACTION_IMPL_DIR)?;
let mut actions: Vec<String> = Vec::new();
for item in dircontent {
let detail = format!("{}", item?.path().display());
actions.push(detail);
}
Ok(actions
.iter()
.any(|a| a.ends_with(&format!("{}-impl.sh", action_name))))
}

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

@ -1,24 +0,0 @@
#!/bin/bash
mv -f /etc/fstab{,.copy}
# For Debian we need to instal gawk first. It comes only with mawk
if [[ -f /usr/bin/apt ]]; then
apt-get install -qq -y gawk
fi
awk '/[[:space:]]+\/[[:space:]]+/ {print}' /etc/fstab.copy >>/etc/fstab
awk '/[[:space:]]+\/boot[[:space:]]+/ {print}' /etc/fstab.copy >>/etc/fstab
# For Suse
awk '/[[:space:]]+\/boot\/efi[[:space:]]+/ {print}' /etc/fstab.copy >>/etc/fstab
# In case we have a LVM system
awk '/rootvg-homelv/ {print}' /etc/fstab.copy >>/etc/fstab
awk '/rootvg-optlv/ {print}' /etc/fstab.copy >>/etc/fstab
awk '/rootvg-tmplv/ {print}' /etc/fstab.copy >>/etc/fstab
awk '/rootvg-usrlv/ {print}' /etc/fstab.copy >>/etc/fstab
awk '/rootvg-varlv/ {print}' /etc/fstab.copy >>/etc/fstab
echo "Content of fstab after running the script -->"
cat /etc/fstab
exit 0

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

@ -1,75 +0,0 @@
#!/bin/awk
#
# this file is needed for RedHat 6.x distros. The grub.conf file is not regenerated by any tool
# compared to grub2. this is solved with the help of AWK and SED
# All modifications are only related to initrd. As this line is missing quite often after a kernel update
#
BEGIN {
i=0
kernel_version=""
}
$0 ~ /kernel|initrd/ && $0 !~ /^#|.*#/{
grub_directive[i]=$1
directive_value[i]=$2
indexLine[i]=NR
i++
}
#
# Build a substring delimited by '-' but start at the second character
#
#
function substr_c2(_i) {
return substr(directive_value[_i],index(directive_value[_i],"-")+1)
}
#
# Find out whether the grub directive follow the right order or whether we have one missing (initrd)
# In that case we need to know the number of the lines in order to insert an initrd line
#
function directiveMissing() {
k=0
for (j=0; j<i; j++) {
k = j
if ( grub_directive[k] == grub_directive[k+1] ) {
sed_modify="sed -e '" indexLine[k] "ainitrd /initramfs-" substr_c2(k) ".img' /boot/grub/grub.conf"
system(sed_modify)
kernel_version = substr_c2(k)
}
j++
}
}
#
# Find out whether the grub directiveValues for initrd is available
# If it is empty the right value has to be inserted
#
function directiveValueMissing() {
k=0
for (j=0; j<i; j++) {
k = j
if ( length(directive_value[k]) == 0 ) {
sed_modify="sed -e '" indexLine[k] "c\tinitrd /initramfs-" substr_c2(k-1) ".img' /boot/grub/grub.conf"
system(sed_modify)
kernel_version = substr_c2(k-1)
}
}
}
END {
directiveMissing()
directiveValueMissing()
print "Starting recreate of initramfs"
img_str="dracut -f /boot/initramfs-" substr_c2(0) ".img " substr_c2(0)
system(img_str)
print "Recreate of initramfs finished"
}

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

@ -1,76 +0,0 @@
#!/bin/bash
# recover logic for handling and initrd or kernel problem
#
recover_suse() {
kernel_type=$(uname -r | grep -q default && echo "kernel-default" || echo "kernel-azure")
kernel_version=$(zypper se -is ${kernel_type} | grep ${kernel_type} | awk '{print $7;exit}')
kernel_version=$(sed -e "s/kernel-//" <<< $(rpm -q kernel --last | head -n 1 | cut -f1 -d' '))
# Get sure that all required modles are loaded
sed -i s/add_driver.*/add_drivers+="hv_vmbushv_netvschv_storvsc"/ /etc/dracut.conf
mkinitrd /boot/initrd-"${kernel_version}" "$kernel_version"
grub2-mkconfig -o /boot/grub2/grub.cfg
}
recover_ubuntu() {
if [[ ! -e /var/log/dpkg.log ]]; then
# if this file is empty we have to assume that we have a vanilla system. Only one kernel available
kernel_version=$(ls /boot/vmlinuz-*)
kernel_version=${kernel_version#/boot/vmlinuz-}
else
kernel_version=$( zgrep linux-image /var/log/dpkg.log* | grep installed | cut -d' ' -f5 | cut -d':' -f1 | sed -e 's/linux-image-//' | grep ^[1-9] | sort -V | tail -n 1)
fi
# This is needed on Debian only
if [[ -e /boot/initrd.img-${kernel_version} ]]; then
rm /boot/initrd.img-${kernel_version}
fi
# Get sure that all required modles are loaded
echo "hv_vmbus" >> /etc/initramfs-tools/modules
echo "hv_storvsc" >> /etc/initramfs-tools/modules
echo "hv_netvsc" >> /etc/initramfs-tools/modules
update-initramfs -k "$kernel_version" -c
update-grub
}
#
# Should handle all redhat based distros
#
recover_redhat() {
kernel_version=$(sed -e "s/kernel-//" <<< $(rpm -q kernel --last | head -n 1 | cut -f1 -d' '))
# Get sure that all required modles are loaded
sed -i s/add_driver.*/add_drivers+="hv_vmbushv_netvschv_storvsc"/ /etc/dracut.conf
if [[ "$isRedHat6" == "true" ]]; then
# verify the grub.conf and correct it if needed
cd "$tmp_dir"
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.\?[0-2]\?\"' /etc/os-release) -eq 0 ]]; then
for installed_kernel in $(rpm -qa kernel); do
kernel-install add $(sed 's/kernel-//' <<< $installed_kernel) /boot/vmlinuz-$(sed 's/kernel-//' <<< $installed_kernel)
done
else
depmod ${kernel_version}
mkinitrd --force /boot/initramfs-"${kernel_version}".img "$kernel_version"
grub2-mkconfig -o /boot/grub2/grub.cfg
fi
fi
}
if [[ "$isRedHat" == "true" ]]; then
recover_redhat
fi
if [[ "$isSuse" == "true" ]]; then
recover_suse
fi
if [[ "$isUbuntu" == "true" ]]; then
recover_ubuntu
fi
exit 0

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

@ -1,52 +0,0 @@
#!/bin/bash
# The main intention is to roll back to the previous working kernel
# We do this by altering the grub configuration
# From the man page
# Set the default boot menu entry for GRUB. This requires setting GRUB_DEFAULT=saved in /etc/default/grub
set_grub_default() {
# verify whether GRUB_DEFAULT is available
grep -q 'GRUB_DEFAULT=.*' /etc/default/grub || echo 'GRUB_DEFAULT=saved' >>/etc/default/grub
# The next line could be garded and/or improved with the help of an if for instance
# though I keep it simple
sed -i "s/GRUB_DEFAULT=[[:digit:]]/GRUB_DEFAULT=saved/" /etc/default/grub
}
# set the default kernel accordingly
# This is different for RedHat and Ubuntu/SUSE distros
# Ubuntu and SLES use sub-menues
# Variables are set by action.rs
if [[ $isRedHat == "true" ]]; then
if [[ $isRedHat6 == "true" ]]; then
grubby --set-default=1 # This is the previous kernel
ldconfig
else
set_grub_default
# set to previous kernel
sed -i -e 's/GRUB_DEFAULT=.*/GRUB_DEFAULT=1/' /etc/default/grub
# Generate both config files.
grub2-mkconfig -o /boot/efi/EFI/$(ls /boot/efi/EFI | grep -i -E "centos|redhat")/grub.cfg
grub2-mkconfig -o /boot/grub2/grub.cfg
# enable sysreq
echo "kernel.sysrq = 1" >>/etc/sysctl.conf
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
set_grub_default
sed -i -e 's/GRUB_DEFAULT=.*/GRUB_DEFAULT="1>2"/' /etc/default/grub
grub2-mkconfig -o /boot/grub2/grub.cfg
fi
# For reference --> https://www.linuxsecrets.com/2815-grub2-submenu-change-boot-order
exit 0

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

@ -1,146 +0,0 @@
#!/bin/bash
#
# serialconsole-impl is responsible to set the configuration for the serialconsole
# correct in case this is missing in a VM image.
# It also enables sysreq to allow a reboot from the Portal
#
enable_sysreq() {
if [[ $isRedHat == "true" ]]; then
echo "kernel.sysrq = 1" >> /etc/sysctl.d/90-alar2.conf
else
echo "kernel.sysrq = 1" >> /etc/sysctl.conf
fi
}
serial_fix_suse_redhat (){
if [[ "$isRedHat6" == "true" ]]; then
echo "Configuring the serialconsole for RedHat 6.x is not implemented"
exit 1
fi
grub_file="/etc/default/grub"
enable_sysreq
if [[ -f $grub_file ]]; then
sed -i 's/GRUB_TIMEOUT=.*/GRUB_TIMEOUT=30/' $grub_file
grep -Eq '^GRUB_CMDLINE_LINUX.*' $grub_file
if [[ $? -eq 0 ]]; then
sed -i '/GRUB_CMDLINE_LINUX.*/s/"$//; s|GRUB_CMDLINE_LINUX.*|& console=tty1 console=ttyS0,115200n8 earlyprintk=ttyS0,115200"|' $grub_file
else
echo 'GRUB_CMDLINE_LINUX="console=tty1 console=ttyS0,115200n8 earlyprintk=ttyS0,115200"' >> $grub_file
fi
# modify terminal
grep -q 'GRUB_TERMINAL' $grub_file
if [[ $? -eq 0 ]]; then
sed -i 's/GRUB_TERMINAL.*/GRUB_TERMINAL="serial"/' $grub_file
else
echo 'GRUB_TERMINAL="serial"' >> $grub_file
fi
# modify GRUB serial
grep -q 'GRUB_SERIAL_COMMAND' $grub_file
if [[ $? -eq 0 ]]; then
sed -i 's/GRUB_SERIAL_COMMAND.*/GRUB_SERIAL_COMMAND="serial --speed=9600 --unit=0 --word=8 --parity=no --stop=1"/' $grub_file
else
echo 'GRUB_SERIAL_COMMAND="serial --speed=9600 --unit=0 --word=8 --parity=no --stop=1"' >> $grub_file
fi
grep -q 'GRUB_TIMEOUT_STYLE' $grub_file
if [[ $? -eq 0 ]]; then
sed -i 's/GRUB_TIMEOUT_STYLE.*//' $grub_file
fi
else
# file does not exist
touch $grub_file
cat << EOF > $grub_file
GRUB_TIMEOUT=30
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL="serial"
GRUB_CMDLINE_LINUX="console=tty1 console=ttyS0 earlyprintk=ttyS0 rootdelay=300"
GRUB_DISABLE_RECOVERY="true"
GRUB_SERIAL_COMMAND="serial --speed=9600 --unit=0 --word=8 --parity=no --stop=1"
EOF
fi
# update grub
if [[ -d /sys/firmware/efi ]]; then
if [[ $isRedHat == "true" ]]; then
grub2-mkconfig -o /boot/efi/EFI/$(grep '^ID=' /etc/os-release | cut -d '"' -f2)/grub.cfg
fi
else
grub2-mkconfig -o /boot/grub2/grub.cfg
fi
}
# REDHAT/CENTOS PART
if [[ "$isRedHat" == "true" ]]; then
serial_fix_suse_redhat
fi
# SUSE PART
if [[ "$isSuse" == "true" ]]; then
serial_fix_suse_redhat
fi
# UBUNTU PART
# if #1
if [[ "$isUbuntu" == "true" ]]; then
grub_file="/etc/default/grub.d/50-cloudimg-settings.cfg"
enable_sysreq
# if #2
if [[ -f $grub_file ]]; then
sed -i 's/GRUB_TIMEOUT=.*/GRUB_TIMEOUT=10/' $grub_file
grep -Eq '^GRUB_CMDLINE_LINUX.*' $grub_file
# if #3
if [[ $? -eq 0 ]]; then
sed -i '/GRUB_CMDLINE_LINUX.*/s/"$//; s|GRUB_CMDLINE_LINUX.*|& console=tty1 console=ttyS0 earlyprintk=ttyS0"|' $grub_file
else
echo 'GRUB_CMDLINE_LINUX="console=tty1 console=ttyS0 earlyprintk=ttyS0"' >> $grub_file
fi # close if#3
# modify GRUB serial if required
grep -q "GRUB_TERMINAL=serial" $grub_file
# if#4
if [[ $? -ne 0 ]]; then
echo "GRUB_TERMINAL=serial" >> $grub_file
else
# make a full replacement
sed -i 's/GRUB_SERIAL_COMMAND.*/GRUB_SERIAL_COMMAND="serial --speed=9600 --unit=0 --word=8 --parity=no --stop=1"/' $grub_file
fi # close if#4
else
# file does not exist
touch $grub_file
cat $grub_file << EOF
# Set the default commandline
GRUB_CMDLINE_LINUX="console=tty1 console=ttyS0 earlyprintk=ttyS0"
GRUB_CMDLINE_LINUX_DEFAULT=""
# Set the grub console type
GRUB_TERMINAL=serial
# Set the serial command
GRUB_SERIAL_COMMAND="serial --speed=9600 --unit=0 --word=8 --parity=no --stop=1"
# Set the recordfail timeout
GRUB_RECORDFAIL_TIMEOUT=30
# Wait briefly on grub prompt
GRUB_TIMEOUT=10
EOF
fi # close if#2
# update grub
update-grub
fi # close if#1

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

@ -1,6 +0,0 @@
#!/bin/bash
# This is just a simple demo in order to print out the environment seen by the script
# The calling process is preparing the environment accordingly
printenv
pwd

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

@ -1,287 +0,0 @@
use crate::constants;
use crate::distro;
use crate::helper;
use crate::mount;
use crate::redhat;
use crate::ubuntu;
/*
At first we need to find out whether we have to work on an encrypted OS
We can do this with lsblk in order to find out whether we have a device with the name osencrypt available
lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 48M 0 disk
sda1 8:1 0 46M 0 part /mnt/azure_bek_disk
sdb 8:16 0 30G 0 disk
sdb1 8:17 0 29.9G 0 part /
sdb14 8:30 0 4M 0 part
sdb15 8:31 0 106M 0 part /boot/efi
sdc 8:32 0 64G 0 disk
sdc1 8:33 0 500M 0 part /tmp/dev/sdc1
sdc2 8:34 0 500M 0 part /investigateroot/boot
sdc3 8:35 0 2M 0 part
sdc4 8:36 0 63G 0 part
osencrypt 253:0 0 63G 0 crypt
rootvg-tmplv 253:1 0 2G 0 lvm /investigateroot/tmp
rootvg-usrlv 253:2 0 10G 0 lvm /investigateroot/usr
rootvg-optlv 253:3 0 2G 0 lvm /investigateroot/opt
rootvg-homelv 253:4 0 1G 0 lvm /investigateroot/home
rootvg-varlv 253:5 0 8G 0 lvm /investigateroot/var
rootvg-rootlv 253:6 0 2G 0 lvm /investigateroot
sdd 8:48 0 50G 0 disk
sdd1 8:49 0 50G 0 part /mnt
sr0 11:0 1 628K 0 rom
In the next step it is required to unmount all of LVM LVs.
This is due to the fact that we need to do a fs-check on all of the partitions. This we have to do for the boot
and EFI partition as well.
In the next step we mount them again on the usual paths for ALAR
------
On a non LVM system we need to do the similar steps
On an Ubuntu 16.x distro we have these details
lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 50G 0 disk
sda1 8:1 0 50G 0 part /mnt
sdb 8:16 0 48M 0 disk
sdb1 8:17 0 46M 0 part /mnt/azure_bek_disk
sdc 8:32 0 30G 0 disk
sdc1 8:33 0 29.9G 0 part /
sdc14 8:46 0 4M 0 part
sdc15 8:47 0 106M 0 part /boot/efi
sdd 8:48 0 30G 0 disk
sdd1 8:49 0 29.7G 0 part
osencrypt 253:0 0 29.7G 0 crypt /investigateroot
sdd2 8:50 0 256M 0 part /investigateroot/boot
sdd14 8:62 0 4M 0 part
sdd15 8:63 0 106M 0 part /tmp/dev/sdd15
sr0 11:0 1 628K 0 rom
Ubuntu 16 or 18 don't have a seperate boot partition
If ADE is used on them an extra partition is created to store the boot and luks part on an not encrypted
partition
*/
pub(crate) fn is_ade_enabled() -> bool {
cmd_lib::run_cmd!(lsblk | grep -q osencrypt).is_ok()
}
pub(crate) fn do_ubuntu_ade(mut partition_info: Vec<String>, mut distro: &mut distro::Distro) {
helper::log_info("This is a recent Ubuntu 16.x/18.x with ADE enabled");
// Get EFI partition
partition_info.retain(|x| x.contains("EF00")); //Get the UEFI partition
helper::set_efi_part_number_and_fs(distro, &partition_info[0]);
helper::set_efi_part_path(distro);
helper::fsck_partition(
helper::get_efi_part_path(distro).as_str(),
helper::get_efi_part_fs(distro).as_str(),
);
// Set the root_part_path manually
distro.rescue_root.root_part_path = constants::OSENCRYPT_PATH.to_string();
set_root_part_fs(distro);
// Due to the changed partition layout on an ADE enabled OS we have to set the boot partiton details
// We use hardcoded values in this case
distro.boot_part.boot_part_fs = "ext2".to_string();
distro.boot_part.boot_part_number = 2;
distro.boot_part.boot_part_path = format!(
"{}{}",
helper::read_link(constants::RESCUE_DISK),
distro.boot_part.boot_part_number
);
// Due to the fact that we have already mounted filesystems for ADE on a repair-vm
// we need to unmount them first before we can do a fsck on each of the partitions
umount_investigations(distro);
fsck_partitions(distro);
ubuntu::verify_ubuntu(distro);
}
pub(crate) fn do_redhat_nolvm_ade(partition_info: Vec<String>, mut distro: &mut distro::Distro) {
// Unfortunately we need to work with hardcoded values as there exist no label information
distro.boot_part.boot_part_fs = "xfs".to_string();
distro.boot_part.boot_part_number = 1;
set_root_part_fs(distro);
distro.rescue_root.root_part_number = 2;
// Set the root_part_path manually for ADE
distro.rescue_root.root_part_path = constants::OSENCRYPT_PATH.to_string();
//For EFI partition we use normal logic in order to setup the details correct
for partition in partition_info.iter() {
if partition.contains("EFI") {
helper::set_efi_part_number_and_fs(distro, partition);
}
}
distro.boot_part.boot_part_path = format!(
"{}{}",
helper::read_link(constants::RESCUE_DISK),
distro.boot_part.boot_part_number
);
helper::set_efi_part_path(distro);
//Unmount the investigation path, otherwise the fsck isn't possible
umount_investigations(distro);
fsck_partitions(distro);
redhat::verify_redhat_nolvm(distro);
}
pub(crate) fn do_redhat6_or_7_ade(partition_info: Vec<String>, mut distro: &mut distro::Distro) {
println!("6_7 info : {:?}", &partition_info);
if let Some(root_info) = partition_info.iter().find(|x| x.contains("GiB")) {
distro.rescue_root.root_part_number = helper::get_partition_number_detail(root_info);
distro.rescue_root.root_part_path = format!(
"{}{}",
helper::read_link(constants::RESCUE_DISK),
distro.rescue_root.root_part_number
);
}
if let Some(boot_info) = partition_info.iter().find(|x| x.contains("MiB")) {
distro.boot_part.boot_part_fs = helper::get_partition_filesystem_detail(boot_info);
distro.boot_part.boot_part_number = helper::get_partition_number_detail(boot_info);
distro.boot_part.boot_part_path = format!(
"{}{}",
helper::read_link(constants::RESCUE_DISK),
distro.boot_part.boot_part_number
);
}
// Set the root_part_path manually for ADE
distro.rescue_root.root_part_path = constants::OSENCRYPT_PATH.to_string();
set_root_part_fs(distro);
//Unmount the investigation path, otherwise the fsck isn't possible
umount_investigations(distro);
fsck_partitions(distro);
redhat::verify_redhat_nolvm(distro);
}
pub(crate) fn do_redhat_lvm_ade(mut partition_info: Vec<String>, mut distro: &mut distro::Distro) {
/*
Unfortunately we need to work with hardcoded values as there exist no label information
Number Start End Size File system Name Flags
1 1049kB 525MB 524MB fat16 EFI System Partition boot, esp
2 525MB 1050MB 524MB xfs msftdata
3 1050MB 1052MB 2097kB bios_grub
4 1052MB 68.7GB 67.7GB lvm
*/
// Get the right partitions
// Get the boot partition first
let mut partition_info_copy = partition_info.to_owned(); // we need a copy for later usage
partition_info.retain(|x| !(x.contains("EF00") || x.contains("EF02") || x.contains("8E00"))); //remove the UEFI, the bios_boot partition
distro.boot_part.boot_part_fs = helper::get_partition_filesystem_detail(&partition_info[0]);
distro.boot_part.boot_part_number = helper::get_partition_number_detail(&partition_info[0]);
set_root_part_fs(distro);
distro.rescue_root.root_part_number = 4;
// Set the root_part_path manually for ADE
distro.rescue_root.root_part_path = constants::OSENCRYPT_PATH.to_string();
//For EFI partition we use normal logic in order to setup the details correct
partition_info_copy.retain(|x| x.contains("EF00")); //Get the UEFI partition only
helper::set_efi_part_number_and_fs(distro, &partition_info_copy[0]);
distro.boot_part.boot_part_path = format!(
"{}{}",
helper::read_link(constants::RESCUE_DISK),
distro.boot_part.boot_part_number
);
helper::set_efi_part_path(distro);
// LVM mounts need to be removed. We need to remount them later
umount_investigations_lvm();
//Unmount the investigation path, otherwise the fsck isn't possible
umount_investigations(distro);
fsck_partitions(distro);
// Set the LVM path details in order to work with ADE
distro.lvm_details.lvm_root_part = redhat::lvm_path_helper("rootlv");
distro.lvm_details.lvm_usr_part = redhat::lvm_path_helper("usrlv");
distro.lvm_details.lvm_var_part = redhat::lvm_path_helper("varlv");
redhat::verify_redhat_lvm(distro);
}
fn fsck_partitions(distro: &distro::Distro) {
helper::fsck_partition(
distro.rescue_root.root_part_path.as_str(),
distro.rescue_root.root_part_fs.as_str(),
);
helper::fsck_partition(
distro.boot_part.boot_part_path.as_str(),
distro.boot_part.boot_part_fs.as_str(),
);
helper::fsck_partition(
helper::get_efi_part_path(distro).as_str(),
helper::get_efi_part_fs(distro).as_str(),
);
}
fn umount_investigations(distro: &distro::Distro) {
// umount EFI
if helper::has_efi_part(distro) {
mount::umount(
helper::get_ade_mounpoint(helper::get_efi_part_path(distro).as_str()).as_str(),
);
}
// umount boot
mount::umount(helper::get_ade_mounpoint(distro.boot_part.boot_part_path.as_str()).as_str());
// umount osencrypt
if !distro.is_lvm {
// If it is LVM we have already unmounted the '/investigationroot'
mount::umount(
helper::get_ade_mounpoint(distro.rescue_root.root_part_path.as_str()).as_str(),
);
}
}
fn umount_investigations_lvm() {
/*
These are the mounts we have to remove
sdc4 8:36 0 63G 0 part
osencrypt 253:0 0 63G 0 crypt
rootvg-tmplv 253:1 0 2G 0 lvm /investigateroot/tmp
rootvg-usrlv 253:2 0 10G 0 lvm /investigateroot/usr
rootvg-optlv 253:3 0 2G 0 lvm /investigateroot/opt
rootvg-homelv 253:4 0 1G 0 lvm /investigateroot/home
rootvg-varlv 253:5 0 8G 0 lvm /investigateroot/var
rootvg-rootlv 253:6 0 2G 0 lvm /investigateroot
*/
mount::umount("/investigateroot/tmp");
mount::umount("/investigateroot/usr");
mount::umount("/investigateroot/opt");
mount::umount("/investigateroot/home");
mount::umount("/investigateroot/var");
mount::umount("/investigateroot");
}
fn set_root_part_fs(mut distro: &mut distro::Distro) {
if let Ok(line) = cmd_lib::run_fun!(lsblk -fn /dev/mapper/osencrypt) {
distro.rescue_root.root_part_fs = helper::cut(line.as_str(), " ", 1).to_string();
}
}

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

@ -1,75 +0,0 @@
/*
The following options and flags need to be available
FLAG
-----
-s --standalone : This should signal that we run in standalone mode. Any required repair scripts need to be downloaded from git
ARGUMENT
--------
Either pass over a single action or many seperated by a comma.
Each action needs then to be verified for its existens on git/filesystem
If the action does exists it gets executed
OPTIONS
--------
-d --dir : The directory in which action-implementations are stored. Can be used for testing of scripts as well.
The standalone flag is necessary to be set as well
*/
use clap::{App, Arg};
pub(crate) struct CliInfo {
pub(crate) standalone: bool,
pub(crate) action_directory: String,
pub(crate) actions: String,
}
impl CliInfo {
pub(crate) fn new() -> Self {
Self { standalone : false, action_directory : "".to_string(), actions : "".to_string(),}
}
}
pub(crate) fn cli() -> CliInfo {
let about = "
ALAR tries to assist with non boot able scenarios by running
one or more different actions in order to get a VM in a running state that allows
the administrator to further recover the VM after it is up, running and accessible again.
";
let matches = App::new("Azure Linux Auto Recover")
.version("0.3.1")
.author("Marcus Lachmanez , malachma@microsoft.com")
.about(about)
.arg(Arg::with_name("standalone")
.short("s")
.long("standalone")
.help("Operates the tool in a standalone mode.")
.takes_value(false))
.arg(Arg::with_name("directory")
.short("d")
.long("directory")
.takes_value(true)
.requires("standalone") // if directory is set
// it is mandatory to have standalone set as well
.help("The directory in which the actions are defined.\nRequires the standalone flag")
)
.arg(Arg::with_name("ACTION")
.help("Sets the input file to use")
.required(true)
.index(1))
.get_matches();
let mut cli_info = CliInfo::new();
// Calling .unwrap() is safe here because "ACTION" is required
// this is true for directory as well if flag standalone is present
cli_info.actions = matches.value_of("ACTION").unwrap().to_string();
cli_info.standalone = matches.is_present("standalone");
if cli_info.standalone && matches.is_present("directory") {
cli_info.action_directory = matches.value_of("directory").unwrap().to_string();
}
cli_info
}

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

@ -1,13 +0,0 @@
pub(crate) static RESCUE_DISK: &str = "/dev/disk/azure/scsi1/lun0";
pub(crate) static RESCUE_ROOT: &str = "/srv/rescue-root/";
pub(crate) static RESCUE_ROOT_RUN: &str = "/srv/rescue-root/run";
pub(crate) static RESCUE_ROOT_BOOT: &str = "/srv/rescue-root/boot";
pub(crate) static RESCUE_ROOT_BOOT_EFI: &str = "/srv/rescue-root/boot/efi";
pub(crate) static RESCUE_ROOT_USR: &str = "/srv/rescue-root/usr";
pub(crate) static RESCUE_ROOT_VAR: &str = "/srv/rescue-root/var";
pub(crate) static SUPPORT_FILESYSTEMS: &str = "dev proc sys tmp dev/pts";
pub(crate) static ASSERT_PATH: &str = "/tmp/assert";
pub(crate) static REDHAT_RELEASE: &str = "/tmp/assert/etc/redhat-release";
pub(crate) static OS_RELEASE: &str = "/tmp/assert/etc/os-release";
pub(crate) static OSENCRYPT_PATH: &str = "/dev/mapper/osencrypt";
pub(crate) static ACTION_IMPL_DIR: &str = "/tmp/action_implementation";

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

@ -1,309 +0,0 @@
use crate::ade;
use crate::constants;
use crate::helper;
use crate::helper::read_link;
use crate::mount;
use crate::redhat;
use crate::suse;
use crate::ubuntu;
use std::process;
#[derive(Debug)]
pub struct Distro {
pub boot_part: BootPartDetails,
pub rescue_root: RootPartDetails,
pub efi_part: EfiPartT,
pub is_lvm: bool,
pub is_ade: bool,
pub lvm_details: LVMDetails,
pub kind: DistroKind,
}
#[derive(Debug, PartialEq)]
pub enum DistroKind {
Debian,
Suse,
RedHatCentOS,
RedHatCentOS6,
Ubuntu,
Undefined,
}
#[derive(Debug)]
pub struct BootPartDetails {
pub(crate) boot_part_fs: String,
pub(crate) boot_part_number: u8,
pub(crate) boot_part_path: String,
}
#[derive(Debug)]
pub struct RootPartDetails {
pub(crate) root_part_fs: String,
pub(crate) root_part_number: u8,
pub(crate) root_part_path: String,
}
#[derive(Debug)]
pub struct LVMDetails {
pub(crate) lvm_root_part: String,
pub(crate) lvm_usr_part: String,
pub(crate) lvm_var_part: String,
}
#[derive(Debug, PartialEq)]
pub struct EfiPartition {
pub(crate) efi_part_number: u8,
pub(crate) efi_part_fs: String,
pub(crate) efi_part_path: String,
}
impl EfiPartition {
fn new() -> Self {
Self {
efi_part_fs: "".to_string(),
efi_part_path: "".to_string(),
efi_part_number: 0,
}
}
}
#[derive(Debug, PartialEq)]
pub enum EfiPartT {
EfiPart(EfiPartition),
NoEFI,
}
impl EfiPartT {
pub fn new() -> EfiPartT {
EfiPartT::EfiPart(EfiPartition::new())
}
}
impl Default for EfiPartT {
fn default() -> Self {
EfiPartT::NoEFI
}
}
impl Default for DistroKind {
fn default() -> Self {
DistroKind::Undefined
}
}
impl BootPartDetails {
fn new() -> Self {
Self {
boot_part_fs: "".to_string(),
boot_part_path: "".to_string(),
boot_part_number: 0,
}
}
}
impl RootPartDetails {
fn new() -> Self {
Self {
root_part_fs: "".to_string(),
root_part_path: "".to_string(),
root_part_number: 0,
}
}
}
impl LVMDetails {
fn new() -> Self {
Self {
lvm_root_part: "".to_string(),
lvm_usr_part: "".to_string(),
lvm_var_part: "".to_string(),
}
}
}
impl Distro {
pub fn new() -> Distro {
let mut partitions: Vec<String> = Vec::new();
//get_partitions is filling the variable partitions
get_partitions(&mut partitions);
let efi_part: EfiPartT = Default::default();
let boot_part: BootPartDetails = BootPartDetails::new();
let root_part: RootPartDetails = RootPartDetails::new();
let kind: DistroKind = Default::default();
let lvm_details = LVMDetails::new();
let mut distro: Distro = Distro {
boot_part,
rescue_root: root_part,
efi_part,
is_lvm: false,
is_ade: false,
lvm_details,
kind,
};
// here we start the core logic in order to determine what distro and type we have to cope with
dispatch(partitions, &mut distro);
distro
}
}
fn get_partitions(partitions: &mut Vec<String>) {
// For testing ALAR we need a conditional compile
let link = read_link(constants::RESCUE_DISK);
let sedscript = r#"s|[ ]\+| |g;s|^[ \t]*||"#;
let out =
cmd_lib::run_fun!(sgdisk ${link} -p | grep -E "^ *[1,2,3,4,5,6]" | sed $sedscript);
// we are only interested in partitions which contain the numbers 1-6. Multiple whitespaces and trailing ones are removed
match out {
Ok(v) => {
for line in v.lines() {
// Need to check if no garbage is in it
if line.contains("GiB") || line.contains("MiB") {
partitions.push(line.to_string());
}
}
helper::log_info(
format!(
"We have the following partitions determined: {:?}",
partitions
)
.as_str(),
);
}
Err(e) => panic!("Error {:?}", e),
}
}
// If there is only one partition detected
fn do_old_ubuntu_or_centos(partition_info: Vec<String>, mut distro: &mut Distro) {
helper::log_info("This could be an old Ubuntu image or even an CentOS with one partition only");
// At first we have to determine whether this is a Ubuntu distro
// or whether it is a single partiton CentOs distro
if let Err(e) = mount::mkdir_assert() {
panic!(
"Creating assert directory is not possible : '{}'. ALAR is not able to proceed further",
e
);
}
distro.rescue_root.root_part_fs = helper::get_partition_filesystem_detail(&partition_info[0]);
distro.rescue_root.root_part_number = helper::get_partition_number_detail(&partition_info[0]);
distro.rescue_root.root_part_path = format!(
"{}{}",
read_link(constants::RESCUE_DISK),
distro.rescue_root.root_part_number
);
helper::fsck_partition(
distro.rescue_root.root_part_path.as_str(),
distro.rescue_root.root_part_fs.as_str(),
);
mount::mount_path_assert(distro.rescue_root.root_part_path.as_str());
let pretty_name = helper::get_pretty_name("/tmp/assert/etc/os-release");
mount::umount(constants::ASSERT_PATH);
if pretty_name.contains("Debian") || pretty_name.contains("Ubuntu") {
distro.kind = DistroKind::Ubuntu;
let _ = mount::rmdir(constants::ASSERT_PATH);
} else {
// Single partiton CentOS
let _ = mount::rmdir(constants::ASSERT_PATH);
redhat::verify_redhat_nolvm(distro);
}
}
// if we have two partition detected
//fn do_red_hat(partition_info: &Vec<String>, distro: &mut Distro) {
fn do_red_hat(partition_info: Vec<String>, distro: &mut Distro) {
helper::log_info("This could be a RedHat/Centos 6/7 image");
redhat::do_redhat6_or_7(partition_info, distro);
}
// if we have 3 partition detected
// Usuall this is a layout for Ubuntu. But recent RedHat RAW images do have this layout as well
fn do_recent_ubuntu_or(partition_info: Vec<String>, distro: &mut Distro) {
helper::log_info(
"This could be a recent Ubuntu 16.x or 18.x image. Or a RedHat with RAW partitions",
);
// We call this function for both Ubuntu and RedHat the logic is the same to get partitions determined
ubuntu::do_ubuntu(partition_info, distro);
// In the next step we figure out what it is
// The order is important otherwise an incorrect distro gets reported
redhat::verify_redhat_nolvm(distro);
ubuntu::verify_ubuntu(distro);
}
// if we have 4 partition detected
fn do_suse_or_lvm_or_ubuntu(partition_info: Vec<String>, distro: &mut Distro) {
// This function is also called if we have an recent Ubuntu distro with ADE enabled
// With ADE a 4th partition got added to hold the boot-part-details plus luks
// Define an enum which is used to decide which further part has to be executed
enum Logic {
RedHat,
Suse,
Ubuntu,
}
let mut which_logic = Logic::RedHat; // Default value is Redhat
// Not sure whether this is a RedHat or CENTOS with LVM or it is a Suse 12/15 instead
// Need to make a simple test
for partition in partition_info.iter() {
if partition.contains("lxboot") {
which_logic = Logic::Suse;
}
}
// Verify if we have an Ubuntu distro with ADE enabled
// This needs to be verified first before we can do the RedHat part instead
// Since with ADE on Ubuntu we got a 4th partition added
if distro.is_ade {
let pretty_name = helper::get_pretty_name("/investigateroot/etc/os-release"); // This path must exists, otherwise it can not be determined
if pretty_name.is_empty() {
helper::log_error("'/investigationrooot' needs to be mounted first. ALAR does stop");
process::exit(1);
}
if pretty_name.contains("Ubuntu") {
which_logic = Logic::Ubuntu;
}
}
match which_logic {
Logic::RedHat => redhat::do_redhat_lvm_or(partition_info, distro),
Logic::Suse => suse::do_suse(partition_info, distro),
Logic::Ubuntu => ade::do_ubuntu_ade(partition_info, distro),
}
}
fn dispatch(partition_info: Vec<String>, mut distro: &mut Distro) {
// Test for an ADE repair environment
distro.is_ade = ade::is_ade_enabled();
helper::log_info(format!("Ade is enabled : {}", distro.is_ade).as_str());
match partition_info.len() {
1 => do_old_ubuntu_or_centos(partition_info, distro),
2 => do_red_hat(partition_info, distro),
3 => do_recent_ubuntu_or(partition_info, distro),
4 => do_suse_or_lvm_or_ubuntu(partition_info, distro),
_ => {
helper::log_error("Unrecognized Linux distribution. ALAR tool is stopped\n
Your OS can not be determined. The OS distros supported are:\n
CentOS/Redhat 6.8 - 8.2\n
Ubuntu 16.4 LTS and Ubuntu 18.4 LTS\n
Suse 12 and 15\n
Debain 9 and 10\n
ALAR will stop!\n
If your OS is in the above list please report this issue at https://github.com/azure/repair-script-library/issues"
);
process::exit(1);
}
}
}

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

@ -1,255 +0,0 @@
use crate::constants;
use crate::distro::{Distro, EfiPartT, EfiPartition};
use crate::mount;
use chrono::prelude::Utc;
use cmd_lib::*;
use std::process::Stdio;
use std::{fs, process};
pub fn log_info(msg: &str) {
println!("[Info {}] {}", Utc::now(), msg);
}
#[allow(dead_code)]
pub fn log_output(msg: &str) {
println!("[Output {}] {}", Utc::now(), msg);
}
#[allow(dead_code)]
pub fn log_warning(msg: &str) {
println!("[Warning {}] {}", Utc::now(), msg);
}
pub fn log_error(msg: &str) {
println!("[Error {}] {}", Utc::now(), msg);
}
pub fn log_debug(msg: &str) {
println!("[Debug {}] {}", Utc::now(), msg);
}
pub(crate) fn read_link(path: &str) -> String {
match fs::canonicalize(&path) {
Ok(value) => return format!("{}", value.display()),
Err(e) => {
log_error(&e.to_string());
panic!("readlink did fail")
}
}
}
pub(crate) fn part_info_helper(sgdiskinfo: &str) -> String {
let part_number = cut(sgdiskinfo, " ", 0).trim_end().parse::<u8>().unwrap();
let path = format!("{}{}", read_link(constants::RESCUE_DISK), part_number);
let run_output = run_fun!(blkid -o export $path);
match run_output {
Ok(value) => value,
Err(_) => "ERROR".to_string(),
}
}
pub(crate) fn cut<'a>(source: &'a str, delimiter: &str, field: usize) -> &'a str {
match source.split(delimiter).nth(field) {
Some(value) => value,
None => {
log_error("String not found. FATAL! ERROR NOT RECOVERABLE");
panic!("Error in function cut");
}
}
}
pub(crate) fn get_partition_number_detail(sgdiskinfo: &str) -> u8 {
cut(sgdiskinfo, " ", 0).parse::<u8>().unwrap()
}
pub(crate) fn get_partition_filesystem_detail(sgdiskinfo: &str) -> String {
let info = part_info_helper(sgdiskinfo);
let mut lines = vec![];
let mut fs_return = "".to_string();
for i in info.lines() {
lines.push(i);
}
lines.retain(|x| x.starts_with("TYPE="));
if let Some(fs) = lines[0].to_string().strip_prefix("TYPE=") {
fs_return = fs.to_string();
}
fs_return
}
pub(crate) fn get_pretty_name(path: &str) -> String {
let mut pretty_name: String = "".to_string();
if let Ok(name) = run_fun!(grep -s PRETTY_NAME $path) {
pretty_name = cut(&name, "=", 1).to_string();
} else if let Ok(value) = fs::read_to_string(constants::REDHAT_RELEASE) {
pretty_name = value;
}
log_info(format!("Pretty Name is : {}", &pretty_name).as_str());
pretty_name
}
pub(crate) fn get_ade_mounpoint(source: &str) -> String {
let mut mountpoint = "".to_string();
if let Ok(path) = cmd_lib::run_fun!(cat /proc/mounts | grep $source | cut -d" " -f2) {
mountpoint = path;
}
log_info(format!("unmounted: {}", &mountpoint).as_str());
mountpoint
}
pub(crate) fn fsck_partition(partition_path: &str, partition_filesystem: &str) {
// Need to handel the condition if no filesystem is available
// This can happen if we have a LVM partition
if partition_filesystem.is_empty() {
return;
}
//let mut result: result::Result<String, io::Error> = Err(io::Error::new(io::ErrorKind::Other, "none")); // run_cmd returns "type CmdResult = Result<(), Error>;"
let mut exit_code = Some(0i32);
match partition_filesystem {
"xfs" => {
log_info(format!("fsck for XFS on {}", partition_path).as_str());
if let Err(e) = mount::mkdir_assert() {
panic!("Creating assert directory is not possible : '{}'. ALAR is not able to proceed further",e);
}
// In case the filesystem has valuable metadata changes in a log which needs to
// be replayed. Mount the filesystem to replay the log, and unmount it before
// re-running xfs_repair
mount::mount_path_assert(partition_path);
mount::umount(constants::ASSERT_PATH);
if let Ok(stat) = process::Command::new("xfs_repair")
.arg(&partition_path)
.stdout(Stdio::null())
.stderr(Stdio::null())
.status()
{
exit_code = stat.code();
}
}
"fat16" => {
log_info("fsck for fat16/vfat");
if let Ok(stat) = process::Command::new("fsck.vfat")
.args(&["-p", partition_path])
.status()
{
exit_code = stat.code();
}
}
_ => {
log_info(format!("fsck for {}", partition_filesystem).as_str());
if let Ok(stat) = process::Command::new(format!("fsck.{}", partition_filesystem))
.args(&["-p", partition_path])
.status()
{
exit_code = stat.code();
}
}
}
match exit_code {
// error 4 is returned by fsck.ext4 only
Some(_code @ 4) => {
log_error(
format!(
"Partition {} can not be repaired in auto mode",
&partition_path
)
.as_str(),
);
log_error("Aborting ALAR");
process::exit(1);
}
// xfs_repair -n returns 1 if the fs is corrupted.
// Also fsck may raise this error but we ignore it as even a normal recover is raising it. FALSE-NEGATIVE
Some(_code @ 1) if partition_filesystem == "xfs" => {
log_error("A general error occured while trying to recover the device ${root_rescue}.");
log_error("Aborting ALAR");
process::exit(1);
}
None => {
panic!(
"fsck operation terminated by signal error. ALAR is not able to proceed further!"
);
}
// Any other error state is not of interest for us
_ => {}
}
log_info("File system check finished");
}
pub(crate) fn set_efi_part_number_and_fs(distro: &mut Distro, partition: &str) {
let mut new_efi_part = EfiPartT::new();
if let EfiPartT::EfiPart(EfiPartition {
efi_part_number: ref mut ref_to_number,
efi_part_fs: ref mut ref_to_efi_part_fs,
efi_part_path: _,
}) = new_efi_part
{
*ref_to_efi_part_fs = get_partition_filesystem_detail(partition);
*ref_to_number = get_partition_number_detail(partition);
}
distro.efi_part = new_efi_part;
}
pub(crate) fn set_efi_part_path(distro: &mut Distro) {
// set_efi_part_path has to be used only after set_efi_part_number_and_fs has been called
let part_number = get_efi_part_number(distro);
if let EfiPartT::EfiPart(EfiPartition {
efi_part_number: _,
efi_part_fs: _,
efi_part_path: ref mut ref_to_efi_part_path,
}) = distro.efi_part
{
*ref_to_efi_part_path = format!("{}{}", read_link(constants::RESCUE_DISK), part_number);
}
}
pub(crate) fn get_efi_part_path(distro: &Distro) -> String {
let mut path: String = String::from("");
if let EfiPartT::EfiPart(EfiPartition {
efi_part_number: _,
efi_part_fs: _,
efi_part_path: ref ref_to_efi_part_path,
}) = distro.efi_part
{
path = ref_to_efi_part_path.to_string();
}
path
}
pub(crate) fn has_efi_part(distro: &Distro) -> bool {
match distro.efi_part {
EfiPartT::NoEFI => false,
EfiPartT::EfiPart(_) => true,
}
}
pub(crate) fn get_efi_part_fs(distro: &Distro) -> String {
let mut fs: String = String::from("");
if let EfiPartT::EfiPart(EfiPartition {
efi_part_number: _,
efi_part_fs: ref ref_to_efi_part_fs,
efi_part_path: _,
}) = distro.efi_part
{
fs = ref_to_efi_part_fs.to_string();
}
fs
}
fn get_efi_part_number(distro: &Distro) -> u8 {
let mut number: u8 = 0;
if let EfiPartT::EfiPart(EfiPartition {
efi_part_number: internal_number,
efi_part_fs: _,
efi_part_path: _,
}) = distro.efi_part
{
number = internal_number;
}
number
}

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

@ -1,97 +0,0 @@
mod action;
mod ade;
mod cli;
mod constants;
mod distro;
mod helper;
mod mount;
mod prepare_action;
mod redhat;
mod standalone;
mod suse;
mod ubuntu;
use std::process;
fn main() {
// First verify we have the right amount of information to operate
let cli_info = cli::cli();
// At first we need to verify the distro we have to work with
// the Distro struct does contain then all of the required information
let distro = distro::Distro::new();
eprintln!("{:?}", distro);
// Do we have a valid distro or not?
if distro.kind == distro::DistroKind::Undefined {
helper::log_error("Unrecognized Linux distribution. ALAR tool is stopped\n
Your OS can not be determined. The OS distros supported are:\n
CentOS/Redhat 6.8 - 8.2\n
Ubuntu 16.4 LTS and Ubuntu 18.4 LTS\n
Suse 12 and 15\n
Debain 9 and 10\n
ALAR will stop!\n
If your OS is in the above list please report this issue at https://github.com/azure/repair-script-library/issues"
);
process::exit(1);
}
// Prepare and mount the partitions. Take into account what distro we have to deal with
match mount::mkdir_rescue_root() {
Ok(_) => {}
Err(e) => panic!(
"The rescue-root dir can't be created. This is not recoverable! : {} ",
e
),
}
// Step 2 of prepare and mount. Mount the right dirs depending on the distro determined
prepare_action::distro_mount(&distro, &cli_info);
// Verify we have an implementation available for the action to be executed
// Define a variable for the error condition that may happen
let mut is_action_error = false;
for action_name in cli_info.actions.split(',') {
match action::is_action_available(action_name) {
// Do the action
Ok(_is @ true) => match action::run_repair_script(&distro, action_name) {
Ok(_) => is_action_error = false,
Err(e) => {
helper::log_error(
format!("Action {} raised an error: '{}'", &action_name, e).as_str(),
);
is_action_error = true;
}
},
Ok(_is @ false) => {
helper::log_error(format!("Action '{}' is not available", action_name).as_str());
is_action_error = true;
}
Err(e) => {
helper::log_error(
format!(
"There was an error raised while verifying the action: '{}'",
e
)
.as_str(),
);
is_action_error = true;
}
}
}
// Umount everything again
prepare_action::distro_umount(&distro);
// Inform the calling process about the success
if is_action_error {
process::exit(1);
} else {
process::exit(0);
}
}

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

@ -1,114 +0,0 @@
use crate::helper;
use crate::constants;
use std::{fs, io, process};
//use sys_mount;
pub(crate) fn mkdir_assert() -> Result<(), io::Error>{
match fs::create_dir_all(constants::ASSERT_PATH) {
Ok(()) => Ok(()) ,
Err(e) => {println!("Error while creating the assert directory: {}", e);
Err(e)
}
}
}
pub(crate) fn mkdir_rescue_root() -> Result<(), io::Error>{
match fs::create_dir_all(constants::RESCUE_ROOT) {
Ok(()) => Ok(()) ,
Err(e) => {println!("Error while creating the rescue-root directory: {}", e);
Err(e)
}
}
}
fn mount( source: &str, destination: &str, option: Option<&str>) {
// There is an issue on Ubuntu that the XFS filesystem is not enabled by default
// We need to load the driver first
match process::Command::new("modprobe").arg("xfs").status() {
Ok(_) => {},
Err(_) => helper::log_error("Loading of the module xfs was not possible. This may result in mount issues! : "),
}
let supported = match sys_mount::SupportedFilesystems::new() {
Ok(supported) => supported,
Err(_) => {
helper::log_error("Failed to get supported file systems");
panic!();
}
};
match sys_mount::Mount::new(source, destination, &supported, sys_mount::MountFlags::empty(), option) {
Ok(_) => {
helper::log_info(format!("mounted {} to {}", source, &destination).as_str() );
}
Err(why) => {
helper::log_error(format!("failed to mount {} to {}: {}", source, destination, why).as_str());
panic!();
}
}
}
pub(crate) fn bind_mount(source: &str, destination: &str) {
let supported = match sys_mount::SupportedFilesystems::new() {
Ok(supported) => supported,
Err(_) => {
helper::log_error("Failed to get supported file systems");
panic!();
}
};
match sys_mount::Mount::new(source, destination, &supported, sys_mount::MountFlags::BIND, None) {
Ok(_) => {
//helper::log_info(format!("mounted {} to {}", source, &destination).as_str() );
}
Err(why) => {
helper::log_error(format!("failed to mount {} to {}: {}", source, destination, why).as_str());
panic!();
}
}
}
pub(crate) fn mount_path_assert(source: &str) {
mount(source, constants::ASSERT_PATH, None);
}
pub(crate) fn mount_root_on_rescue_root(root_source: &str, option: Option<&str>) {
mount(root_source, constants::RESCUE_ROOT, option);
}
pub(crate) fn mount_boot_on_rescue_boot(boot_source: &str, option: Option<&str>) {
mount(boot_source, constants::RESCUE_ROOT_BOOT, option);
}
pub(crate) fn mount_efi_on_rescue_efi(efi_source: &str, option: Option<&str>) {
mount(efi_source, constants::RESCUE_ROOT_BOOT_EFI, option);
}
// Used only for LVM
pub(crate) fn mount_usr_on_rescue_root_usr(usr_source: &str) {
mount(usr_source, constants::RESCUE_ROOT_USR, None);
}
// Used only for LVM
pub(crate) fn mount_var_on_rescue_root_var(var_source: &str) {
mount(var_source, constants::RESCUE_ROOT_VAR, None);
}
pub(crate) fn umount(destination: &str) {
match sys_mount::unmount(destination, sys_mount::UnmountFlags::DETACH) {
Ok(()) => (),
Err(why) => {
helper::log_error(format!("Failed to unmount {}: {}", destination, why).as_str());
helper::log_error("This shouldn't cause a severe issue for ALAR.");
}
}
}
pub(crate) fn rmdir(path: &str) -> std::io::Result<()> {
fs::remove_dir_all(path)?;
Ok(())
}

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

@ -1,254 +0,0 @@
use crate::cli;
use crate::constants;
use crate::distro;
use crate::distro::DistroKind;
use crate::helper;
use crate::mount;
use crate::standalone;
use fs_extra::dir;
use std::{env, fs, io, process};
pub(crate) fn ubuntu_mount(distro: &distro::Distro) {
// We have to verify also whether we have old Ubuntus/Debian with one partition only
// Or whether we have also an EFI partition available
mount::mount_root_on_rescue_root(distro.rescue_root.root_part_path.as_str(), None);
// If ADE is enabled the extra boot partition needs to be mounted
if distro.is_ade {
mount::mount_boot_on_rescue_boot(distro.boot_part.boot_part_path.as_str(), None);
}
let mount_option: Option<&str>;
if distro.efi_part != distro::EfiPartT::NoEFI {
if helper::get_efi_part_fs(distro) == "xfs" {
mount_option = Some("nouuid");
} else {
mount_option = None;
}
mount::mount_efi_on_rescue_efi(helper::get_efi_part_path(distro).as_str(), mount_option);
}
mount_support_filesystem();
mount::bind_mount("/run", constants::RESCUE_ROOT_RUN);
}
pub(crate) fn ubuntu_umount(distro: &distro::Distro) {
umount_support_filesystem();
mount::umount(constants::RESCUE_ROOT_RUN);
if distro.efi_part != distro::EfiPartT::NoEFI {
mount::umount(constants::RESCUE_ROOT_BOOT_EFI);
}
// If ADE is enabled for Ubuntu the boot partition needs to be unmounted first
if distro.is_ade {
mount::umount(constants::RESCUE_ROOT_BOOT);
}
mount::umount(constants::RESCUE_ROOT);
}
pub(crate) fn suse_mount(distro: &distro::Distro) {
redhat_mount(distro); // We can use the same functionality
}
pub(crate) fn suse_umount(distro: &distro::Distro) {
redhat_umount(distro); // we can use the same functionality
}
pub(crate) fn redhat_mount(distro: &distro::Distro) {
if distro.is_lvm {
let mut mount_option: Option<&str>;
mount::mount_root_on_rescue_root(distro.lvm_details.lvm_root_part.as_str(), None);
mount::mount_usr_on_rescue_root_usr(distro.lvm_details.lvm_usr_part.as_str());
mount::mount_var_on_rescue_root_var(distro.lvm_details.lvm_var_part.as_str());
if distro.boot_part.boot_part_fs == "xfs" {
mount_option = Some("nouuid");
} else {
mount_option = None;
}
mount::mount_boot_on_rescue_boot(distro.boot_part.boot_part_path.as_str(), mount_option);
if helper::get_efi_part_fs(distro) == "xfs" {
mount_option = Some("nouuid");
} else {
mount_option = None;
}
mount::mount_efi_on_rescue_efi(helper::get_efi_part_path(distro).as_str(), mount_option);
mount_support_filesystem();
} else {
// if we have an XFS filesystem we have to set the 'nouuid' option
let mut mount_option: Option<&str>;
if distro.rescue_root.root_part_fs == "xfs" {
mount_option = Some("nouuid");
} else {
mount_option = None;
}
mount::mount_root_on_rescue_root(distro.rescue_root.root_part_path.as_str(), mount_option);
if distro.boot_part.boot_part_fs == "xfs" {
mount_option = Some("nouuid");
} else {
mount_option = None;
}
// if no boot partition is available we skip this step
// this is required if we have the special condition that a RedHat RAW image does only have 3 partitons
// root, EF00 and EF02
if distro.boot_part.boot_part_number != 0 {
mount::mount_boot_on_rescue_boot(
distro.boot_part.boot_part_path.as_str(),
mount_option,
);
}
if distro.efi_part != distro::EfiPartT::NoEFI {
if helper::get_efi_part_fs(distro) == "xfs" {
mount_option = Some("nouuid");
} else {
mount_option = None;
}
mount::mount_efi_on_rescue_efi(
helper::get_efi_part_path(distro).as_str(),
mount_option,
);
}
mount_support_filesystem();
}
}
pub(crate) fn redhat6_mount(distro: &distro::Distro) {
mount::mount_root_on_rescue_root(distro.rescue_root.root_part_path.as_str(), None);
// In case we have no boot part information like on a single CentOS distro we don't need to mount boot
if distro.boot_part.boot_part_number != 0 {
mount::mount_boot_on_rescue_boot(distro.boot_part.boot_part_path.as_str(), None);
}
mount_support_filesystem();
}
pub(crate) fn redhat6_umount(distro: &distro::Distro) {
umount_support_filesystem();
// In case we have no boot part information like on a single CentOS distro we don't need to umount boot
if distro.boot_part.boot_part_number != 0 {
mount::umount(constants::RESCUE_ROOT_BOOT);
}
mount::umount(constants::RESCUE_ROOT);
}
pub(crate) fn redhat_umount(distro: &distro::Distro) {
if distro.is_lvm {
umount_support_filesystem();
mount::umount(constants::RESCUE_ROOT_BOOT_EFI);
mount::umount(constants::RESCUE_ROOT_BOOT);
mount::umount(constants::RESCUE_ROOT_USR);
mount::umount(constants::RESCUE_ROOT_VAR);
mount::umount(constants::RESCUE_ROOT);
} else {
umount_support_filesystem();
if distro.efi_part != distro::EfiPartT::NoEFI {
mount::umount(constants::RESCUE_ROOT_BOOT_EFI);
}
// if no boot partition is available we skip this step
// this is required if we have the special condition that a RedHat RAW image does only have 3 partitons
// root, EF00 and EF02
if distro.boot_part.boot_part_number != 0 {
mount::umount(constants::RESCUE_ROOT_BOOT);
}
mount::umount(constants::RESCUE_ROOT);
}
}
fn mount_support_filesystem() {
match mkdir_support_filesystems() {
Ok(()) => {}
Err(e) => panic!(
"Support Filesystems are not able to be created. This is not recoverable : {}",
e
),
}
for fs in constants::SUPPORT_FILESYSTEMS.to_string().split(' ') {
mount::bind_mount(
format!("/{}/", fs).as_str(),
format!("{}{}", constants::RESCUE_ROOT, fs).as_str(),
);
}
}
fn umount_support_filesystem() {
for fs in constants::SUPPORT_FILESYSTEMS.to_string().rsplit(' ') {
mount::umount(format!("{}{}", constants::RESCUE_ROOT, fs).as_str());
}
}
fn mkdir_support_filesystems() -> io::Result<()> {
for fs in constants::SUPPORT_FILESYSTEMS.to_string().split(' ') {
fs::create_dir_all(format!("{}{}", constants::RESCUE_ROOT, fs))?;
}
Ok(())
}
pub(crate) fn distro_mount(distro: &distro::Distro, cli_info: &cli::CliInfo) {
match distro.kind {
DistroKind::Debian | DistroKind::Ubuntu => ubuntu_mount(distro),
DistroKind::Suse => suse_mount(distro),
DistroKind::RedHatCentOS => redhat_mount(distro),
DistroKind::RedHatCentOS6 => redhat6_mount(distro),
DistroKind::Undefined => {} // Nothing to do here we have covered this condition already
}
// Also copy the recovery scripts to /tmp in order to make them available for the chroot
// operation we do later
copy_actions_totmp(distro, cli_info);
}
pub(crate) fn distro_umount(distro: &distro::Distro) {
match distro.kind {
DistroKind::Debian | DistroKind::Ubuntu => ubuntu_umount(distro),
DistroKind::Suse => suse_umount(distro),
DistroKind::RedHatCentOS => redhat_umount(distro),
DistroKind::RedHatCentOS6 => redhat6_umount(distro),
DistroKind::Undefined => {} // Nothing to do here we have covered this condition already
}
}
fn copy_actions_totmp(distro: &distro::Distro, cli_info: &cli::CliInfo) {
// We need to copy the action scripts to /tmp
// This is the directory chroot can access
if let Err(err) = fs::remove_dir_all(constants::ACTION_IMPL_DIR) {
println!(
"Directory {} can not be removed : '{}'",
constants::ACTION_IMPL_DIR,
err
);
}
if !cli_info.standalone {
let mut options = dir::CopyOptions::new(); //Initialize default values for CopyOptions
options.skip_exist = true;
match env::current_dir() {
Ok(cd) => println!("The current dir is : {}", cd.display()),
Err(e) => println!("Error : {}", e),
}
// base directory already set correct by linux-alar2.sh
match dir::copy("src/action_implementation", "/tmp", &options) {
Ok(_) => {}
Err(e) => {
println!("Copy operation for action_implementation directory failed. ALAR needs to stop: {}", e);
distro_umount(distro);
process::exit(1);
}
}
} else if let Err(e) = standalone::download_action_scripts(cli_info) {
distro_umount(distro);
panic!(
"action scripts are not able to be copied or downloadable : '{}'",
e
);
}
}

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

@ -1,296 +0,0 @@
#![allow(non_snake_case)]
use crate::ade;
use crate::constants;
use crate::distro;
use crate::helper;
use crate::mount;
use cmd_lib::{run_cmd, run_fun};
pub(crate) fn do_redhat_lvm_or(partition_info: Vec<String>, distro: &mut distro::Distro) {
let mut contains_lvm_partition: bool = false;
for partition in partition_info.iter() {
if partition.contains("8E00") {
contains_lvm_partition = true;
}
}
if contains_lvm_partition {
do_redhat_lvm(partition_info, distro);
} else if partition_info.len() == 1 {
do_centos_single_partition(distro);
} else {
do_redhat_nolvm(partition_info, distro);
}
}
pub(crate) fn do_redhat6_or_7(partition_info: Vec<String>, mut distro: &mut distro::Distro) {
// this function does handle the condition if only two partitions are available
if !distro.is_ade {
if let Some(root_info) = partition_info.iter().find(|x| x.contains("GiB")) {
distro.rescue_root.root_part_fs = helper::get_partition_filesystem_detail(root_info);
distro.rescue_root.root_part_number = helper::get_partition_number_detail(root_info);
distro.rescue_root.root_part_path = format!(
"{}{}",
helper::read_link(constants::RESCUE_DISK),
distro.rescue_root.root_part_number
);
}
if let Some(boot_info) = partition_info.iter().find(|x| x.contains("MiB")) {
distro.boot_part.boot_part_fs = helper::get_partition_filesystem_detail(boot_info);
distro.boot_part.boot_part_number = helper::get_partition_number_detail(boot_info);
distro.boot_part.boot_part_path = format!(
"{}{}",
helper::read_link(constants::RESCUE_DISK),
distro.boot_part.boot_part_number
);
}
distro.boot_part.boot_part_path = format!(
"{}{}",
helper::read_link(constants::RESCUE_DISK),
distro.boot_part.boot_part_number
);
helper::fsck_partition(
distro.rescue_root.root_part_path.as_str(),
distro.rescue_root.root_part_fs.as_str(),
);
helper::fsck_partition(
distro.boot_part.boot_part_path.as_str(),
distro.boot_part.boot_part_fs.as_str(),
);
verify_redhat_nolvm(distro);
} else {
// ADE part
ade::do_redhat6_or_7_ade(partition_info, distro);
}
}
fn do_redhat_nolvm(mut partition_info: Vec<String>, mut distro: &mut distro::Distro) {
if !distro.is_ade {
// 4 partitions with no LVM we find on an 'CentOS Linux release 7.7.1908' for instance
/*
Number Start End Size File system Name Flags
14 1049kB 5243kB 4194kB bios_grub
15 5243kB 524MB 519MB fat16 EFI System Partition boot
1 525MB 1050MB 524MB xfs
2 1050MB 32.2GB 31.2GB xfs
*/
helper::log_info(
"This is a recent RedHat or CentOS image with 4 partitions and no LVM signature",
);
distro.is_lvm = false;
if let Some(uefi) = partition_info.iter().by_ref().find(|x| x.contains("EF00")) {
helper::set_efi_part_number_and_fs(distro, uefi);
helper::set_efi_part_path(distro);
}
partition_info.retain(|x| !(x.contains("EF00") || x.contains("EF02")));
//remove the UEFI the bios_boot partition. We have two partitions left
// We need to determine what part is the root and what part is the boot one.
if let Some(root_info) = partition_info.iter().find(|x| x.contains("GiB")) {
distro.rescue_root.root_part_fs = helper::get_partition_filesystem_detail(root_info);
distro.rescue_root.root_part_number = helper::get_partition_number_detail(root_info);
distro.rescue_root.root_part_path = format!(
"{}{}",
helper::read_link(constants::RESCUE_DISK),
distro.rescue_root.root_part_number
);
}
if let Some(boot_info) = partition_info.iter().find(|x| x.contains("MiB")) {
distro.boot_part.boot_part_fs = helper::get_partition_filesystem_detail(boot_info);
distro.boot_part.boot_part_number = helper::get_partition_number_detail(boot_info);
distro.boot_part.boot_part_path = format!(
"{}{}",
helper::read_link(constants::RESCUE_DISK),
distro.boot_part.boot_part_number
);
}
distro.boot_part.boot_part_path = format!(
"{}{}",
helper::read_link(constants::RESCUE_DISK),
distro.boot_part.boot_part_number
);
helper::fsck_partition(
distro.rescue_root.root_part_path.as_str(),
distro.rescue_root.root_part_fs.as_str(),
);
helper::fsck_partition(
distro.boot_part.boot_part_path.as_str(),
distro.boot_part.boot_part_fs.as_str(),
);
helper::fsck_partition(
helper::get_efi_part_path(distro).as_str(),
helper::get_efi_part_fs(distro).as_str(),
);
verify_redhat_nolvm(distro);
} else {
// This an ADE enabled OS
helper::log_info(
"This is a recent RedHat or CentOS image with 4 partitions and no LVM signature",
);
helper::log_info("An ADE signature got identified");
distro.is_lvm = false;
ade::do_redhat_nolvm_ade(partition_info, distro);
}
}
fn do_redhat_lvm(mut partition_info: Vec<String>, mut distro: &mut distro::Distro) {
helper::log_info("This is a recent RedHat or CentOS image with 4 partitions and LVM signature");
distro.is_lvm = true;
// At first we need to prepare the LVM setup
match run_cmd!(pvscan -q -q; vgscan -q -q; lvscan -q -q;) {
Ok(_) => {}
Err(error) => panic!("There is a problem to setup LVM correct. {}", error),
}
if !distro.is_ade {
if let Some(lvm_info) = partition_info.iter().find(|x| x.contains("8E00")) {
distro.rescue_root.root_part_fs = helper::get_partition_filesystem_detail(lvm_info);
distro.rescue_root.root_part_number = helper::get_partition_number_detail(lvm_info);
distro.rescue_root.root_part_path = format!(
"{}{}",
helper::read_link(constants::RESCUE_DISK),
distro.rescue_root.root_part_number
);
}
if let Some(uefi) = partition_info.iter().by_ref().find(|x| x.contains("EF00")) {
helper::set_efi_part_number_and_fs(distro, uefi);
helper::set_efi_part_path(distro);
}
partition_info
.retain(|x| !(x.contains("EF00") || x.contains("EF02") || x.contains("8E00")));
//remove the UEFI the bios_boot and the root partition to get the boot partition only
distro.boot_part.boot_part_fs = helper::get_partition_filesystem_detail(&partition_info[0]);
distro.boot_part.boot_part_number = helper::get_partition_number_detail(&partition_info[0]);
distro.boot_part.boot_part_path = format!(
"{}{}",
helper::read_link(constants::RESCUE_DISK),
distro.boot_part.boot_part_number
);
distro.boot_part.boot_part_path = format!(
"{}{}",
helper::read_link(constants::RESCUE_DISK),
distro.boot_part.boot_part_number
);
helper::fsck_partition(
distro.rescue_root.root_part_path.as_str(),
distro.rescue_root.root_part_fs.as_str(),
);
helper::fsck_partition(
distro.boot_part.boot_part_path.as_str(),
distro.boot_part.boot_part_fs.as_str(),
);
helper::fsck_partition(
helper::get_efi_part_path(distro).as_str(),
helper::get_efi_part_fs(distro).as_str(),
);
// Set the path details for later usage
distro.lvm_details.lvm_root_part = lvm_path_helper("rootlv");
distro.lvm_details.lvm_usr_part = lvm_path_helper("usrlv");
distro.lvm_details.lvm_var_part = lvm_path_helper("varlv");
helper::log_info(&format!("LVM Details '{:?}'", &distro.lvm_details));
verify_redhat_lvm(distro);
} else {
// Ade part
helper::log_info(
"This is a recent RedHat or CentOS image with 4 partitions and LVM signature",
);
helper::log_info("An ADE signature got identified");
ade::do_redhat_lvm_ade(partition_info, distro);
}
}
// verify_redhat_nolvm does set the DistroKind to either RedHatCentOS or RedHatCentOS6
// if the verification is succesful
pub(crate) fn verify_redhat_nolvm(distro: &mut distro::Distro) {
if let Err(e) = mount::mkdir_assert() {
panic!(
"Creating assert directory is not possible : {}. ALAR is not able to proceed further",
e
);
}
mount::mount_path_assert(distro.rescue_root.root_part_path.as_str());
set_redhat_kind(distro);
mount::umount(constants::ASSERT_PATH);
if mount::rmdir(constants::ASSERT_PATH).is_err() {
helper::log_debug("ASSERT_PATH can not be removed. This is a minor issue. ALAR is able to continue further");
}
}
pub(crate) fn verify_redhat_lvm(distro: &mut distro::Distro) {
if let Err(e) = mount::mkdir_assert() {
panic!(
"Creating assert directory is not possible : {}. ALAR is not able to proceed further",
e
);
}
mount::mount_path_assert(distro.lvm_details.lvm_root_part.as_str());
set_redhat_kind(distro);
mount::umount(constants::ASSERT_PATH);
}
fn set_redhat_kind(mut distro: &mut distro::Distro) {
let pretty_name = helper::get_pretty_name(constants::OS_RELEASE);
if pretty_name.contains("6.") {
helper::log_info(format!("Pretty Name is : {}", &pretty_name).as_str());
distro.kind = distro::DistroKind::RedHatCentOS6;
} else {
helper::log_info(format!("Pretty Name is : {}", &pretty_name).as_str());
distro.kind = distro::DistroKind::RedHatCentOS;
}
}
pub(crate) fn lvm_path_helper(lvname: &str) -> String {
let mut lvpath: String = "".to_string();
if let Ok(value) = run_fun!(lvscan | grep $lvname) {
if let Some(path) = value.split('\'').nth(1) {
lvpath = path.to_string();
}
}
lvpath
}
pub(crate) fn do_centos_single_partition(mut distro: &mut distro::Distro) {
// It is safe to use hardcoded values
distro.rescue_root.root_part_path =
format!("{}{}", helper::read_link(constants::RESCUE_DISK), 1);
helper::fsck_partition(
distro.rescue_root.root_part_path.as_str(),
distro.rescue_root.root_part_fs.as_str(),
);
// We have a single partition only boot and efi partitions do not need to be set
verify_redhat_nolvm(distro);
}

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

@ -1,40 +0,0 @@
use crate::helper;
use crate::cli;
use crate::constants;
use std::{io,process,fs};
pub(crate) fn download_action_scripts(cli_info: &cli::CliInfo) -> io::Result<()> {
if cli_info.action_directory.is_empty() {
// First download the git archive
// Process::Command used in order to ensure we finish the download process
if let Ok(mut child) = process::Command::new("curl").args(&["-o","/tmp/alar2.tar.gz","-L","https://api.github.com/repos/Azure/repair-script-library/tarball/master"]).spawn() {
child.wait().expect("Archive alar2.tar.gz not downloaded");
} else {
helper::log_error("Command curl not executed");
process::exit(1);
}
// Expand the action_implementation directory
cmd_lib::run_cmd!(tar --wildcards --strip-component=7 -xzf /tmp/alar2.tar.gz -C /tmp *src/linux/common/helpers/alar2/src/action_implementation)?;
Ok(())
} else {
// In case we have a local directory for our action scripts we need to copy the actions to
// tmp/action_implementation
if let Err(e) = load_local_action(cli_info.action_directory.as_str()) {
return Err(io::Error::new(io::ErrorKind::Other, format!("Load local action failed : '{}'",e)));
}
Ok(())
}
}
fn load_local_action(directory_source: &str) -> fs_extra::error::Result<u64> {
let _ = fs::remove_dir_all(constants::ACTION_IMPL_DIR);
let mut options = fs_extra::dir::CopyOptions::new();
options.skip_exist = true;
options.copy_inside = true;
match fs_extra::dir::copy(directory_source, constants::ACTION_IMPL_DIR, &options) {
Ok(v) => Ok(v),
Err(e) => Err(e),
}
}

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

@ -1,57 +0,0 @@
use crate::constants;
use crate::distro;
use crate::helper;
pub(crate) fn do_suse(mut partition_info: Vec<String>, mut distro: &mut distro::Distro) {
if !distro.is_ade {
distro.kind = distro::DistroKind::Suse;
if let Some(uefi) = partition_info.iter().by_ref().find(|x| x.contains("EF00")) {
helper::set_efi_part_number_and_fs(distro, uefi);
helper::set_efi_part_path(distro);
}
partition_info.retain(|x| !(x.contains("EF00") || x.contains("EF02")));
//remove the UEFI the bios_boot partition. We have two partitions left
// We need to determine what part is the root and what part is the boot one.
if let Some(root_info) = partition_info.iter().find(|x| x.contains("GiB")) {
distro.rescue_root.root_part_fs = helper::get_partition_filesystem_detail(root_info);
distro.rescue_root.root_part_number = helper::get_partition_number_detail(root_info);
distro.rescue_root.root_part_path = format!(
"{}{}",
helper::read_link(constants::RESCUE_DISK),
distro.rescue_root.root_part_number
);
}
if let Some(boot_info) = partition_info.iter().find(|x| x.contains("MiB")) {
distro.boot_part.boot_part_fs = helper::get_partition_filesystem_detail(boot_info);
distro.boot_part.boot_part_number = helper::get_partition_number_detail(boot_info);
distro.boot_part.boot_part_path = format!(
"{}{}",
helper::read_link(constants::RESCUE_DISK),
distro.boot_part.boot_part_number
);
}
helper::fsck_partition(
distro.rescue_root.root_part_path.as_str(),
distro.rescue_root.root_part_fs.as_str(),
);
helper::fsck_partition(
distro.boot_part.boot_part_path.as_str(),
distro.boot_part.boot_part_fs.as_str(),
);
helper::fsck_partition(
helper::get_efi_part_path(distro).as_str(),
helper::get_efi_part_fs(distro).as_str(),
);
} else {
// ADE part
// Not yet available
// See --> https://docs.microsoft.com/en-us/azure/virtual-machines/linux/disk-encryption-overview
}
}

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

@ -1,63 +0,0 @@
#![allow(non_snake_case)]
use crate::constants;
use crate::distro;
use crate::helper;
use crate::mount;
pub(crate) fn verify_ubuntu(mut distro: &mut distro::Distro) {
if let Err(e) = mount::mkdir_assert() {
panic!(
"Creating assert directory is not possible: {} ALAR is not able to proceed further",
e
);
}
mount::mount_path_assert(distro.rescue_root.root_part_path.as_str());
let pretty_name = helper::get_pretty_name(constants::OS_RELEASE);
mount::umount(constants::ASSERT_PATH);
if mount::rmdir(constants::ASSERT_PATH).is_err() {
helper::log_debug("ASSERT_PATH can not be removed. This is a minor issue. ALAR is able to continue further");
}
if pretty_name.contains("Ubuntu") {
distro.kind = distro::DistroKind::Ubuntu;
}
if pretty_name.contains("Debian") {
distro.kind = distro::DistroKind::Debian;
}
}
pub(crate) fn do_ubuntu(mut partition_info: Vec<String>, mut distro: &mut distro::Distro) {
// Get the right partitions
// Get the root partition info first
let mut partition_info_copy = partition_info.to_owned(); // we need a copy for later usage
partition_info.retain(|x| !(x.contains("EF00") || x.contains("EF02")) ); //remove the UEFI and the bios_boot partition
distro.rescue_root.root_part_fs = helper::get_partition_filesystem_detail(&partition_info[0]);
distro.rescue_root.root_part_number = helper::get_partition_number_detail(&partition_info[0]);
distro.rescue_root.root_part_path = format!("{}{}", helper::read_link(constants::RESCUE_DISK),distro.rescue_root.root_part_number);
helper::log_info(&distro.rescue_root.root_part_path);
helper::fsck_partition(
distro.rescue_root.root_part_path.as_str(),
distro.rescue_root.root_part_fs.as_str(),
);
// Get EFI partition
partition_info_copy.retain(|x| x.contains("EF00")); //Get the UEFI partition
helper::set_efi_part_number_and_fs(distro, &partition_info_copy[0]);
helper::set_efi_part_path(distro);
helper::fsck_partition(
helper::get_efi_part_path(distro).as_str(),
helper::get_efi_part_fs(distro).as_str(),
);
//verify_ubuntu(distro);
}

Двоичный файл не отображается.