#!/bin/bash /usr/scripts/python.sh
# -*- coding: utf-8 -*-
#
# Auteur : Pierre-Elliott Bécue <becue@crans.org>
# Inspiré du travail de Jérémie Dimino <jeremie@dimino.org>
# Licence : BSD3

import sys
import os
from gestion.affich_tools import coul
import udev_get_iscsi_name as ugin
import subprocess

PATH = "/dev/disk/by-path/"

def store_iscsi_volumes():
    """Extrait la liste des volumes
    de /dev/disk/by-path/ip-*"""

    links = {}
    # os.listdir retourne une liste désordonnée, l'idée est de privilégier
    # l'ordre lexicographique pour que l'état du retour soit identifié.
    state = subprocess.Popen(['ls', PATH], stdout=subprocess.PIPE)
    state = state.stdout.readlines()
    for line in state:
        line = line.replace('\n', '')
        if line.startswith('ip-'):
            if "storage.p2000g3" in line:
                baie = "nols"
            else:
                baie = "slon"
            device = os.readlink(PATH+line) # de la forme ../../sdb42
            device = device.rsplit('/', 1)[1]
            symlink = 'iscsi_' + ugin.getname(device, baie)
            if line.rsplit('-', 1)[1][0:4] == "part":
                lun = line.rsplit('-', 2)[1]
            else:
                lun = line.rsplit('-', 1)[1]
            if links.has_key(lun):
                if not (True in [(symlink in tup) for tup in links[lun]]):
                    links[lun].append((symlink, device))
            else:
                links[lun] = [(symlink, device)]
    return links

def make_link(couple):
    """Crée le symlink /dev/iscsi_nom -> /dev/sdb42"""

    os.chdir("/dev/")
    res = []
    for (sym, dev) in couple:
        diskstatus = subprocess.Popen(['file', '-sb', '/dev/' + dev], stdout=subprocess.PIPE)
        diskstatus = diskstatus.stdout.readlines()[0]
        if not (os.path.islink(sym)) and not 'empty' in diskstatus and not 'ERROR' in diskstatus:
            sys.stdout.write("Création du lien /dev/" + sym + " -> /dev/" + dev + " … ")
            try:
                os.symlink(dev, sym)
                res.append(True)
                sys.stdout.write(coul("OK", 'vert'))
            except:
                res.append(False)
                sys.stdout.write(coul("ECHEC", 'rouge'))
            sys.stdout.write('\n')
        elif os.path.islink(sym) and ('empty' in diskstatus or 'ERROR' in diskstatus):
            sys.stdout.write("Destruction du lien /dev/" + sym + " … ")
            try:
                os.remove(sym)
                res.append(True)
                sys.stdout.write(coul("OK", 'vert'))
            except:
                res.append(False)
                sys.stdout.write(coul("ECHEC", 'rouge'))
            sys.stdout.write('\n')
        elif os.path.islink(sym) and os.readlink(sym) != dev:
            sys.stdout.write("Mise à jour du lien /dev/" + sym + " -> /dev/" + dev + " … ")
            try:
                os.remove(sym)
                os.symlink(dev, sym)
                res.append(True)
                sys.stdout.write(coul("OK", 'vert'))
            except:
                res.append(False)
                sys.stdout.write(coul("ECHEC", 'rouge'))
            sys.stdout.write('\n')
        else:
            res.append(None)
    return res

def clean_iscsi_links():
    """Nettoie les liens présents dans /dev/iscsi_*"""
    links = {}
    # os.listdir retourne une liste désordonnée, l'idée est de privilégier
    # l'ordre lexicographique pour que l'état du retour soit identifié.
    state = subprocess.Popen(['ls', '/dev'], stdout=subprocess.PIPE)
    state = state.stdout.readlines()
    for line in state:
        line = line.replace('\n', '')
        if line.startswith('iscsi_'):
            device = os.readlink('/dev/'+line) # de la forme ../../sdb42
            symlink = line
            make_link([(symlink, device)])
    return links

if __name__ == '__main__':
    if "-h" in sys.argv or "--help" in sys.argv:
        print "Usage: udev_update_symlinks.py <options>"
        print "       -h, --help : print this message and exit"
        print "       --clean : clean empty links no longer referenced"
    if "--clean" in sys.argv:
        clean_iscsi_links()
    nothing = True
    links = store_iscsi_volumes()
    for path in links.keys():
        cmd = make_link(links[path])
        if True in cmd or False in cmd:
            nothing = False

    if nothing:
        sys.stdout.write("Terminé, pas de changement pour les liens.\n")
    else:
        sys.stdout.write("Terminé.\n")
