Untitled

 avatar
unknown
python
5 months ago
15 kB
5
Indexable
#!/usr/bin/python3

from fabric import Connection, Config
import getpass
import time
import re
import sys

nfs_pat = re.compile(r'^[^\s]+\s+([^\s]+)\s+nfs\s+')  # nfs --> mount point
fstab_file = '/etc/fstab'  # fstab

# COLORS
BBLUE = "\033[1;34m"
BPURP="\033[1;35m"
BGREEN = "\033[1;32m"
BRED = "\033[1;31m"
BCYAN = "\033[1;36m"
BWHITE = "\033[1;37m"
BYEL = '\033[1;33m'
GREEN = "\033[0;32m"
GWHITE = "\033[0;47m"   #background colored
GYELL = "\033[0;43m"    #background colored 
RESET_C = "\033[0m"     #reset color default

#({RESET_C}{BRED}V{RESET_C}{BBLUE}F{RESET_C}{BWHITE})

def logo_vf():
    print(f"======={BWHITE}=================================================={RESET_C}{BCYAN}====={RESET_C}{BWHITE}===={RESET_C}")
    print(f"   **\t{BCYAN}|{RESET_C}{BWHITE}/_______{RESET_C}{BBLUE}____{RESET_C}{BWHITE}__________||_______{RESET_C}{BBLUE}______{RESET_C}{BWHITE}_______\--/_______||{RESET_C}")
    print(f"   {BYEL}VF{RESET_C}\t{BCYAN}|{RESET_C}{BWHITE}||{RESET_C}      \t\t\t\t\t\t{BWHITE}||{RESET_C}") 
    print(f"========{BCYAN}|{RESET_C}{BWHITE}||{RESET_C}  {BRED}   RHEL7 TO RHEL8{RESET_C}{BCYAN} UPGRADE{RESET_C}{BWHITE} {RESET_C}{BWHITE}\t\t\t\t||{RESET_C}")
    print(f"{BWHITE}|-{RESET_C}{BRED}----{RESET_C}{BWHITE}{RESET_C}{BRED}{RESET_C}{BWHITE}--{RESET_C}{BCYAN}|{RESET_C}{BWHITE}|{RESET_C}{BBLUE}\_______{RESET_C}{BWHITE}_______________________/--\______-_______{RESET_C}{BBLUE}_____{RESET_C}{BBLUE}{RESET_C}{BWHITE}/|{RESET_C}")
    #print(f\t"{BCYAN}|{RESET_C}{BWHITE}|{RESET_C}  {BYEL}\(|)/{RESET_C}\t\t\t\t\t\t{BWHITE}||{RESET_C}")
    print(f"{BWHITE}|-{RESET_C}{BRED}----{RESET_C}{BWHITE}--|{RESET_C}{BCYAN}{RESET_C}" + f"{BWHITE}="* 55 + f"{BCYAN}/{RESET_C}{BWHITE}|{RESET_C}")
    print(f"{BCYAN}|\{RESET_C}" + f"{BWHITE}="* 62 + f"||")
    print(f"{BCYAN}||-{RESET_C}\t\t\t\t\t\t\t{BWHITE}\t|-{RESET_C}")
    print(f"{BCYAN}||-{RESET_C}\t\t\t\t\t\t\t{BWHITE}\t|-{RESET_C}")
    print(f"{BCYAN}||{RESET_C}")
    print(f"{BCYAN}|{RESET_C}{BWHITE}|{RESET_C}{BCYAN}\---{BWHITE}{RESET_C}------{BCYAN}---{BWHITE}---.{RESET_C}{BCYAN} Connect to {RESET_C}{BWHITE}HOST{RESET_C}{BCYAN}: [ {RESET_C}{BRED}{target_x}{RESET_C}{BCYAN} ]{RESET_C}")
    print(f"{BCYAN}|{RESET_C}{BWHITE}|{RESET_C}{BCYAN}|{RESET_C}")



def os_check(ssh_con):
    os_ver = ssh_con.run('cat /etc/redhat-release', hide=True, warn=True).stdout.split()
    return os_ver

def enablerepo(ssh_con):
    print(f"{BCYAN}||{RESET_C}")
    print(f"{BCYAN}[*]{RESET_C}{BYEL} Enabling Repositories for RHEL 7 and RHEL 8....{RESET_C}")
    ssh_con.run('subscription-manager refresh').stdout
    ssh_con.run('subscription-manager repos --enable rhel-7-server-rpms').stdout
    ssh_con.run('subscription-manager repos --enable rhel-7-server-extras-rpms').stdout
    ssh_con.run('subscription-manager release --unset').stdout

    set_local_rs = ssh_con.run('cat /etc/locale.conf',hide=True).stdout
    if set_local_rs.find("en_US.UTF-8") == -1:
        print(f"{BCYAN}[*]{RESET_C}{BYEL} Setting locale.conf to [LANG=en_US.UTF-8]{RESET_C}")
        ssh_con.sudo('localectl set-locale LANG=en_US.UTF-8', warn=True)

def yum_update(ssh_con):
    print(f"{BCYAN}||{RESET_C}")
    print(f"{BCYAN}[*]{RESET_C}{BYEL} System update (YUM)......{RESET_C}")
    time.sleep(2)
    ssh_con.run('yum update -y')

def umount_nfs_path(ssh_con):
    cmd = ssh_con.run(f'cat {fstab_file}', hide=True)
    mount_lines = cmd.stdout.splitlines()

    mnt_nfs_point = []
    print(f"{BCYAN}||{RESET_C}")
    print(f"{BCYAN}[*]{RESET_C}{BYEL} Unmounting NFS in fstab and mount point....{RESET_C}")
    
    for line in mount_lines:
        if "nfs" in line and re.search('^[^#]', line):
            ssh_con.run(f"sed -i '/^[^#]*nfs/s/^/#/' {fstab_file}")  # comment out fstab
            mnt_nfs_point.append(line.split()[1])  # append mount point


            print(f"{BCYAN}|_-{RESET_C}{BYEL}Umountend in fstab line:{RESET_C}{BBLUE} {line}{RESET_C}")

    for mnt_pt in mnt_nfs_point:
        ssh_con.run(f'umount -l {mnt_pt}', warn=True)  # unmount mount point
        print(f"{BCYAN}|_-{RESET_C}{BYEL}Umounted mount point:{RESET_C}{BBLUE} {mnt_pt}{RESET_C}")
    
    ssh_con.run(f'grep -i nfs* {fstab_file}', warn=True).stdout

def vgs_size_free(ssh_con):
    vg_rs = ssh_con.run('vgs --noheadings -o vg_free --units g systemg' ,warn=True, hide=True)
    size_vg = vg_rs.stdout.strip()

    if size_vg.endswith('g'):
        size_vg = size_vg[:-1]  # Removing trailing 'g'
    vg_free = float(size_vg)
    
    return vg_free

def lvextend_free(ssh_con):
    vg_free_size = vgs_size_free(ssh_con)
    
    if vg_free_size <= 0:
        print(f"{BCYAN}||{RESET_C}")
        print(f"{BCYAN}[*]{RESET_C} {BRED}-Attention!:{RESET_C}{BYEL} No more free space for VG, please create virtual hardisk of size (20G){RESET_C}")
        return
    
    
    if vg_free_size > 6:
        print(f"{BCYAN}||{RESET_C}")
        print(f"{BCYAN}[*]{RESET_C}{BYEL}- Extend LV [systemg-varlv] with (4GB)...{RESET_C}")
        time.sleep(2)
        ssh_con.run(f'lvextend -L +4G /dev/mapper/systemg--varlv -r' ,warn=True)
    elif vg_free_size < 3:
        print(f"{BCYAN}||{RESET_C}")
        print(f"{BCYAN}[*]{RESET_C}{BYEL}- Extend LV [systemg-varlv] with (2GB)...{RESET_C}")
        time.sleep(2)
        ssh_con.run(f'lvextend -L +1G /dev/mapper/systemg-systemg-varlv -r' ,warn=True)     
    elif vg_free_size < 6 and vg_free_size > 4:
        print(f"{BCYAN}||{RESET_C}")
        print(f"{BCYAN}[*]{RESET_C}{BYEL}- Extend LV [systemg-varlv] with (3GB)...{RESET_C}")
        time.sleep(2)
        ssh_con.run(f'lvextend -L +3G /dev/mapper/systemg-varlv -r' ,warn=True)

def leapp_install(ssh_con):
    print(f"{BCYAN}||{RESET_C}")
    print(f"{BCYAN}[*]{RESET_C}{BYEL}- Installing leapp...{RESET_C}")
    time.sleep(2)
    ssh_con.run('yum install -y leapp leapp-repository',warn=True)

def leapp_preupgrade(ssh_con):
    print(f"{BCYAN}||{RESET_C}")
    print(f"{BCYAN}[*]{RESET_C}{BYEL}- Performing [leapp preupgrade]...{RESET_C}")
    ssh_con.run('leapp preupgrade',warn=True)

def leapp_report_handle(ssh_con):
    
    leap_rs = ssh_con.run('cat /var/log/leapp/leapp-report.txt').stdout.splitlines()
    
    print(f"{BCYAN}||{RESET_C}")
    print(f"{BCYAN}[*]{RESET_C}{BYEL}- Handle [leapp report]...{RESET_C}")

    for line in leap_rs:
        if line.find('remove_pam_pkcs11_module_check.confirm=True') != -1:
            print(f"{BCYAN}|_-{RESET_C}{BYEL} remove [pam_pkcs11] module{RESET_C}")
            ssh_con.run('leapp answer --section remove_pam_pkcs11_module_check.confirm=True',warn=True)

        elif line.find('remove_pam_krb5_module_check.confirm=True') != -1:
            print(f"{BCYAN}|_-{RESET_C}{BYEL} remove [pam_krb5] module{RESET_C}")
            ssh_con.run('leapp answer --section remove_pam_krb5_module_check.confirm=True',warn=True)
            
        elif line.find('authselect') != -1:
            print(f"{BCYAN}|_-{RESET_C}{BYEL} set authselect_check True{RESET_C}")
            ssh_con.run('leapp answssh_con = Connectioner --section authselect_check.confirm=True',warn=True)

    print(f"{BCYAN}||{RESET_C}")
    print(f"{BCYAN}[*]{RESET_C}{BYEL}- Remove kernel modules: [floppy] [pata_acpi]...{RESET_C}")

    if 'floppy' in ssh_con.run('lsmod | grep floppy',warn=True).stdout:
        ssh_con.sudo('modprobe -r floppy')
        print("|_- floppy module removed")
    if 'pata_acpi' in ssh_con.run('lsmod | grep pata_acpi',warn=True).stdout:
        ssh_con.sudo('modprobe -r pata_acpi')
        print("|_- pata_acpi module removed")

def leapp_upgrade(ssh_con):
    print(f"{BCYAN}||{RESET_C}")
    print(f"{BCYAN}[*]{RESET_C} {BYEL}- Running [leapp upgrade]...{RESET_C}")
    time.sleep(2)
    ssh_con.run('leapp upgrade',warn=True)

def mount_nfs_point(ssh_con):
    mount_lines = ssh_con.run(f'cat {fstab_file}', hide=True).stdout.splitlines()

    for line in mount_lines:
        if line.startswith('#') and "nfs" in line:
            ssh_con.run(f"sed -i '/^\s*#\s*nfs\s/s/^\s*#\s*//' {fstab_file}")
            #ssh_con.run(f"mount -a")
            #ssh_con.run(f"systemctl daemon-reload")

def post_upgrade(ssh_con2):
    print(f"{BCYAN}||{RESET_C}")
    print(f"{BCYAN}[*]{RESET_C}{BGREEN}-Post tasks Upgrade...{RESET_C}")

    ssh_con2.run(f'cat /etc/redhat-release',warn=True).stdout
    ssh_con2.run(f'uname -r',warn=True).stdout
    ssh_con2.run('subscription-manager list --installed',warn=True).stdout
    ssh_con2.run('subscription-manager release', warn=True)
    ssh_con2.run("alternatives --set python /usr/bin/python3",warn=True) #set python
    time.sleep(5)

def remove_kernel_packages(ssh_con2):
    print(f"{BCYAN}||{RESET_C}") 
    print(f"{BCYAN}[*]{RESET_C}{BGREEN}- Remove old kernels EL7...{RESET_C}")
    ssh_con2.run("yum config-manager --save --setopt exclude=''",warn=True).stdout
    time.sleep(1)
    el7_kernels = ssh_con2.run('cd /lib/modules && ls -d *.el7*',warn=True).stdout.splitlines()
    
    for el7line in el7_kernels:
        el7line = el7line.strip()
        ssh_con2.run(f'[ -x /usr/sbin/weak-modules ] && /usr/sbin/weak-modules --remove-kernel {el7line}',warn=True).stdout
        time.sleep(1)

    for el7line in el7_kernels:
        el7line = el7line.strip()
        ssh_con2.run(f'/bin/kernel-install remove {el7line} /lib/modules/{el7line}/vmlinuz',warn=True)
        time.sleep(1)

    print(f"{BCYAN}||{RESET_C}")
    print(f"{BCYAN}[*]{RESET_C}{BGREEN}- Remove remaining RHEL7 packeges...{RESET_C}")
    #remove remaing rhel7 packages
    ssh_con2.run("rpm -qa | grep -e '\.el[67]' | grep -vE '^(gpg-pubkey|libmodulemd|katello-ca-consumer)' | sort | xargs yum remove -y", warn=True)
    ssh_con2.run('yum remove -y leapp-deps-el8 leapp-repository-deps-el8', warn=True).stdout # Remove leapp dependency
    ssh_con2.run('rm -rf /lib/modules/*el7*', warn=True) #remove remaining empty dir
    ssh_con2.run('rm -rf /var/log/leapp /root/tmp_leapp_py3 /var/lib/leapp',warn=True).stdout
    #Set the current kernel 
    ssh_con2.run('BOOT_OPTIONS="$(tr -s "$IFS" \'\n\' </proc/cmdline | grep -ve \'^BOOT_IMAGE=\' -e \'^initrd=\' | tr lsinitrd /boot/initramfs-*rescue*.img | grep -qm1 "$(uname -r)/kernel/" && echo "OK" || echo "FAIL"\'\n\' \' \')"', hide=True).stdout
    ssh_con2.run('echo $BOOT_OPTIONS > /etc/kernel/cmdline').stdout
    #Replace old existing rescue kernel and initial RAM disk:
    ssh_con2.run("rm /boot/vmlinuz-*rescue* /boot/initramfs-*rescue*",warn=True).stdout;
    ssh_con2.run('/usr/lib/kernel/install.d/51-dracut-rescue.install add "$(uname -r)" /boot "/boot/vmlinuz-$(uname -r)"', warn=True).stdout # reinstall rescue kernel
    
def verify_steps_kernel(ssh_con2):
    print(f"{BCYAN}||{RESET_C}")
    print(f"{BCYAN}[*]{RESET_C}{BGREEN}- Verification steps...{RESET_C}")

    # verify old kernels removed from bootloader entry 
    ssh_con2.run('grubby --info=ALL | grep "\.el7" || echo "Old kernels are not present in the bootloader."', warn=True).stdout
    ssh_con2.run('ls /boot/vmlinuz-*rescue* /boot/initramfs-*rescue*', warn=True).stdout
    ssh_con2.run('grubby --info $(ls /boot/vmlinuz-*rescue*)', warn=True).stdout #verify rescue boot entry 

def wait_for_reboot(host, user, password, timeout=300, interval=10):
    
    start_time = time.time()
    
    while True:
        if time.time() - start_time > timeout:
            print("[-] Timeout waiting for host to come back online.")
            return False
        
        try:
            conn = Connection(host=host, user=user, connect_kwargs={"password": password})
            conn.run('echo "Reconnected!"', hide=True)
            print("[*] Host is back online.")
            return conn  # Return the Connection object if successful
        except Exception as e:
            print(f"[*] Waiting for host to come back online... {e}")
            time.sleep(interval)

def reboot_host_x(host, user, password):

    ssh_con = Connection(host=host, user=user, connect_kwargs={"password": password})
    ssh_con.sudo('reboot now', warn=True)
    ssh_con.close()
    
    while True:
        conn = wait_for_reboot(host, user, password, timeout=300)
        if conn:
            print("[*] Host rebooted successfully.")
            return conn  # Return the Connection object to proceed with post-reboot commands
        else:
            print("[-] Failed to reconnect to the host after reboot. Retrying...")
            time.sleep(10)  # Wait for 10 seconds before retrying

if __name__ == "__main__":
    user_x = "root"
    target_x = "192.168.2.8"  # target host
    
    try:
        #Esstablish connection to host
        logo_vf()
        pass_x = getpass.getpass(f'{BCYAN}[*]{RESET_C}{BRED}- ENTER PASSWORD:_{RESET_C}{BCYAN}>{RESET_C} {RESET_C}')  # Hide password for shell 
        ssh_con = Connection(host=target_x, user=user_x, connect_kwargs={"password": pass_x})

        #OS check
        os_v = os_check(ssh_con)
        time.sleep(1)
        
        if "8.10" in os_v[5]:
            print(f"{BCYAN}||{RESET_C}")
            print(f"{BCYAN}||{RESET_C}")
            print(f"{BCYAN}[*]{RESET_C}{BGREEN}-Great!{RESET_C}:{BYEL} OS version 7.9 detected, we are proceeding...{RESET_C}")
            time.sleep(2)
        else:
            print(f"{BCYAN}||{RESET_C}")
            print(f"{BCYAN}||{RESET_C}")
            print(f"{BCYAN}[*]{RESET_C}{BRED}-Attention!:{RESET_C}{BYEL} OS version 7.9 not detected, connection closed...{RESET_C}")
            sys.exit(1)
        
        # Sequence of tasks before upgraded            
        #enablerepo(ssh_con)
        #yum_update(ssh_con)
        #umount_nfs_path(ssh_con)
        #leapp_install(ssh_con)
        lvextend_free(ssh_con)
        #leapp_preupgrade(ssh_con)
        #leapp_report_handle(ssh_con)
        #leapp_upgrade(ssh_con)
        
        # Reboot host after upgrade:
        ssh_con2 = reboot_host_x(host=target_x, user=user_x, password=pass_x) #second connection object 

        #AFTER REBOOT post upgrade tasks
        if ssh_con2:
            #Call mount nfs function
            #Join SSSD
            #Remove kernel function
            post_upgrade(ssh_con2)
            remove_kernel_packages(ssh_con2)
            verify_steps_kernel(ssh_con2)
        else:
            # Handle failure to reconnect after multiple attempts
            print(f"{BCYAN}||{RESET_C}")
            print(f"{BCYAN}[*]{RESET_C}{BYEL}- Cant connect [ no route to HOST ]{RESET_C}")
    except Exception as e:
        print(f"{BCYAN}||{RESET_C}")
        print(f"{BCYAN}||{RESET_C}")
        print(f"{BCYAN}[*]{RESET_C}{BRED}-Attention!:{RESET_C}{BWHITE} FAIL connecting to HOST - {e}{RESET_C}")
    finally:
        ssh_con.close()

Editor is loading...
Leave a Comment