#!/usr/bin/python3


import sys
import subprocess
import traceback
import hooking

DEFAULT_LV_PATH = "/sys/block"
DEFAULT_SCSI_DEVICE_PATH = "/sys/class/scsi_device"


def _get_name_device(lv):
    shell_command = "ls -l '%s'" % (lv)
    try:
        stdout = subprocess.run(shell_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        LVname = stdout.stdout.decode('utf-8').split("->")[1].replace("../", "").replace("\n", "").strip()
        return LVname
    except:
        sys.stdout.write(" Couldn`t get LV address for device name:"
                         " [%s] " % lv)
        sys.exit(0)


def _get_device_address(lvname):
    shell_command = "ls -l %s/%s/slaves/*/device" % (DEFAULT_LV_PATH, lvname)
    try:
        stdout = subprocess.run(shell_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        LVaddress = stdout.stdout.decode('utf-8').split(" -> ")[1].replace("../", "").replace("\n", "").strip()
        return LVaddress
    except:
        sys.stdout.write(" Couldn`t get LV address for device name:"
                         " [%s] " % lvname)
        sys.exit(2)


def write_conf(lvaddress):
    lv_conf = "%s/%s/device/unpriv_sgio" % (DEFAULT_SCSI_DEVICE_PATH, lvaddress)
    try:
        ps = subprocess.Popen(('echo', '1'), stdout=subprocess.PIPE)
        subprocess.call(["/usr/bin/sudo", "/usr/bin/tee", "root", lv_conf], stdin=ps.stdout,stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    except:
        sys.stdout.write(" Couldn`t create file %s for LV address:"
                         " [%s] " % (lv_conf, lvaddress))
        sys.exit(0)


def main():
    try:
        domxml = hooking.read_domxml()
    except:
        sys.exit(0)
    LV = ""
    list_LV = []
    for disk in domxml.getElementsByTagName('disk'):
        if disk.getAttribute('type') == 'block' and disk.getAttribute('device') == "lun":
            source = disk.getElementsByTagName('source')[0]
            for childNode in source.childNodes:
                if childNode.nodeName == "reservations":
                    reservation = childNode.getAttribute('managed')
                    if reservation == 'yes':
                        LV = source.getAttribute('dev')
                        list_LV.append(LV)
    if len(list_LV) > 0:
        for LV in list_LV:
            if len(LV) > 0:
                lvname = _get_name_device(LV)
                lvaddress = _get_device_address(lvname)
                write_conf(lvaddress)


if __name__ == "__main__":
    try:
        main()
    except:
        hooking.exit_hook('Couldn`t update device with persistent reservations: [unexpected error]: %s\n'
                          % traceback.format_exc())
        sys.exit(0)

