Last active
August 26, 2020 08:09
-
-
Save ClarenceYk/d79d486097350a48ff653ccd028064c8 to your computer and use it in GitHub Desktop.
An example for using rsync to clone a linux system.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
### Colors | |
RED='\e[31m' | |
RED_B='\e[1;37;41m' | |
GREEN='\e[32m' | |
GREEN_B='\e[1;37;42m' | |
YELLOW_B='\e[1;43m' | |
NC='\e[0m' | |
### Tools | |
blkid=/sbin/blkid | |
sfdisk=/sbin/sfdisk | |
### Function for Triming Characters | |
trim_spaces() { | |
echo -n $1 | sed -e "s/^[[:space:]]*//" -e "s/[[:space:]]*$//" | |
} | |
trim_tailing_slashes() { | |
echo -n $1 | sed -e "s/[\/]*$//" | |
} | |
### Functions for result checking | |
check() { | |
if [ $1 -eq 0 ]; then | |
echo -e "${GREEN}Success${NC}" | |
else | |
echo -e "${RED}Failed${NC}"; exit 1 | |
fi | |
} | |
check_without_exit() { | |
if [ $1 -eq 0 ]; then | |
echo -e "${GREEN}Success${NC}" | |
else | |
echo -e "${RED}Failed${NC}" | |
fi | |
} | |
check_empty() { | |
if [ -z $2 ]; then | |
echo -e "${RED_B}Error:${NC} $1 must not be empty"; exit 1 | |
fi | |
} | |
check_ip() { | |
local ip=$1 | |
local stat=1 | |
if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then | |
OIFS=$IFS | |
IFS='.' | |
ip=($ip) | |
IFS=$OIFS | |
[[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \ | |
&& ${ip[2]} -le 255 && ${ip[3]} -le 255 ]] | |
stat=$? | |
fi | |
if [ $stat -ne 0 ]; then | |
echo -e "${RED_B}Error:${NC} $ip is not a volid ip address"; exit 1 | |
fi | |
} | |
### Get partition's UUID | |
get_blkid() { | |
$blkid $1 | cut -f 2 -d " " | cut -f 2 -d "=" | sed -e 's/^"*//' -e 's/"*$//' | |
} | |
### Get block device from user | |
read -p 'Disk you want to use: ' Disk | |
Disk=$( trim_spaces $Disk ) | |
check_empty 'block device' $Disk | |
if [ ! -b $Disk ]; then | |
echo -e "${RED_B}Error:${NC} $Disk is not a block device."; exit 1 | |
fi | |
echo -en "Use ${GREEN_B}${Disk}${NC} as the target device!" | |
read -p ' Continue? (Y/n): ' Confirm | |
if [ "$Confirm" != 'Y' ]; then | |
echo "Canceled by user!"; exit 0 | |
fi | |
### Partition the disk | |
echo -e "${YELLOW_B} ${NC}" | |
echo -e "${YELLOW_B} -> Partition <- ${NC}" | |
echo -e "${YELLOW_B} ${NC}" | |
echo -n 'Destroy old partition table... ' | |
dd if=/dev/zero of=$Disk bs=1024 count=1 &> /dev/null | |
check $? | |
echo -n 'Create new partition table... ' | |
$sfdisk --force $Disk &> /dev/null << EOF | |
1M,4G,S, | |
,,L,* | |
EOF | |
check $? | |
echo -en "Format new partition ${GREEN_B}${Disk}1${NC} to swap... " | |
mkswap ${Disk}1 &> /dev/null | |
check $? | |
echo -en "Format new partition ${GREEN_B}${Disk}2${NC} to ext4... " | |
mkfs.ext4 ${Disk}2 &> /dev/null | |
check $? | |
### Sync system files from source | |
echo -e "${YELLOW_B} ${NC}" | |
echo -e "${YELLOW_B} -> Synchronization <- ${NC}" | |
echo -e "${YELLOW_B} ${NC}" | |
read -p 'Source host IP: ' rsync_ip | |
rsync_ip=$( trim_spaces $rsync_ip ) | |
check_ip $rsync_ip | |
read -p "Which section to use in source host(default 'all'): " rsync_section | |
rsync_section=$( trim_spaces $rsync_section ) | |
if [ -z $rsync_section ]; then | |
rsync_section='all' | |
fi | |
read -p "Which dir to sync in source host(default '/mnt/debian_10'): " rsync_dir | |
rsync_dir=$( trim_spaces $rsync_dir ) | |
if [ -z $rsync_dir ]; then | |
rsync_dir='/mnt/debian_10/' | |
else | |
if [ $rsync_dir != "/" ]; then | |
rsync_dir=$( trim_tailing_slashes $rsync_dir ) | |
rsync_dir=${rsync_dir}/ | |
fi | |
fi | |
echo -n 'Check connectivity... ' | |
ping -c 1 $rsync_ip &> /dev/null | |
check $? | |
rsync_mount='/mnt/rsync_tmp' | |
echo -n "Mount ${Disk}2 to ${rsync_mount}... " | |
mkdir -p $rsync_mount &> /dev/null | |
mount ${Disk}2 $rsync_mount &> /dev/null | |
check $? | |
echo -n "Sync from ${rsync_ip}:${rsync_section}:${rsync_dir} ... " | |
rsync -avHX ${rsync_ip}::${rsync_section}${rsync_dir} ${rsync_mount}/ \ | |
--exclude={/dev/*,/proc/*,/sys/*,/tmp/*,/run/*,/mnt/*,/media/*,/lost+found} \ | |
&> /dev/null | |
check $? | |
### Create /etc/fstab | |
echo -e "${YELLOW_B} ${NC}" | |
echo -e "${YELLOW_B} -> Rebuild GRUB <- ${NC}" | |
echo -e "${YELLOW_B} ${NC}" | |
echo -n 'Generate /etc/fstab... ' | |
cat << EOF > /tmp/fstab | |
# /etc/fstab: static file system information. | |
# | |
# Use 'blkid' to print the universally unique identifier for a | |
# device; this may be used with UUID= as a more robust way to name devices | |
# that works even if disks are added and removed. See fstab(5). | |
# | |
# <file system> <mount point> <type> <options> <dump> <pass> | |
UUID=$( get_blkid ${Disk}2 ) / ext4 errors=remount-ro 0 1 | |
UUID=$( get_blkid ${Disk}1 ) none swap sw 0 0 | |
EOF | |
check $? | |
cp -v /tmp/fstab ${rsync_mount}/etc/fstab | |
### Create shell script for updating grub | |
echo -n 'Generate update_grub.sh... ' | |
cat << EOF > /tmp/update_grub.sh | |
#!/bin/bash | |
grub-install ${Disk} | |
update-grub | |
EOF | |
chmod +x /tmp/update_grub.sh | |
check $? | |
cp -v /tmp/update_grub.sh ${rsync_mount}/tmp/update_grub.sh | |
### Reinstall GRUB | |
echo -n 'Reinstall GRUB... ' | |
mount --bind /proc ${rsync_mount}/proc | |
mount --bind /sys ${rsync_mount}/sys | |
mount --bind /dev ${rsync_mount}/dev | |
mount --bind /run ${rsync_mount}/run | |
chroot ${rsync_mount} /tmp/update_grub.sh &> /dev/null | |
check $? | |
echo -e "${GREEN_B} ${NC}" | |
echo -e "${GREEN_B} -> Install Success! <- ${NC}" | |
echo -e "${GREEN_B} ${NC}" | |
### Script end | |
read -p ' Reboot Now? (Y/n): ' reboot | |
if [ "$reboot" = 'Y' ]; then | |
reboot | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment