ALAR fragments removed
This commit is contained in:
Родитель
ffa4f7f96f
Коммит
4f8d31927c
|
@ -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 didn’t 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
|
|
@ -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 didn’t 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_vmbus hv_netvsc hv_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_vmbus hv_netvsc hv_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);
|
||||
}
|
Двоичные данные
src/linux/common/helpers/alar2/target/debug/alar2
Двоичные данные
src/linux/common/helpers/alar2/target/debug/alar2
Двоичный файл не отображается.
Загрузка…
Ссылка в новой задаче