#!/usr/bin/env python

# Copyright (C) 2014
# EMC Corporation. All rights reserved.

# Checks for "Error detected in journal in LKG (aka alternate) /var partition.
# If error is found, gathers the messages file from LKG /var.

import os
import subprocess
import sys

import isi.app.lib.procs as procs
import isi.sys.bootdisk as bootdisk

def main():
    # Determine if we have an imdd or gmirror node
    imdd_status, imdd_out = procs.get_cmd_output('isi_imdd_status')
    is_geom = bootdisk.current_system_is_geom()

    # Check to see which /var is mounted for imdd or geom node, assign value to
    # dev_entry string
    dev_entry = ""
    mount_list = bootdisk.mountlist()
    if mount_list and is_geom:
        for item in mount_list:
            if '/dev/mirror/var0' in item:
                dev_entry = '/dev/mirror/var1'
            if '/dev/mirror/var1' in item:
                dev_entry = '/dev/mirror/var0'
    elif not mount_list and is_geom:
        print("ERROR: Could not get mount status of alternate /var, no "
              "gather initiated.")
        sys.exit(1)
    else:
        imdd_entry = None
        if (not imdd_out or any('Unknown command' in x for x in imdd_out) or
            any('No such file or directory' in x for x in imdd_out)):
            print("ERROR: Could not get imdd status, no gather initiated.")
            sys.exit(1)
        first_twed = None
        for line in imdd_out:
            if 'var lkg' in line:
                first_twed = line.split()[0]
                break
        for line in imdd_out:
            if first_twed in line:
                imdd_entry = line.split()[0]
                break
        if imdd_entry:
            dev_entry = os.path.join('/dev/', imdd_entry)

    # Mount alternate /var, search for error
    if dev_entry:
        # Create mount point for alternate /var
        mount_pt = '/mnt/varjournalgather'
        if not os.path.exists(mount_pt):
            try:
                os.makedirs(mount_pt)
            except OSError as error:
                if error.errno != errno.EEXIST:
                    print("ERROR: Could not create alternate /var mount "
                          "point, no gather initiated.")
                    sys.exit(1)

        mount_cmd = 'mount %s %s' % (dev_entry, mount_pt)
        mount_status, mount_out = procs.get_cmd_output(mount_cmd)
        if mount_status:
            print("ERROR: Could not mount alternate /var, no gather initiated.")
            try:
                os.rmdir(mount_pt)
            except OSError:
                print("Could not remove alternate /var mount point. Mount "
                      "point may not be unmounted.")
            sys.exit(1)
        full_path = os.path.join(mount_pt, 'log/messages')

        # Gather if necessary
        journal_cmd = 'grep "Error detected in journal" %s' % full_path
        journal_status, journal_out = procs.get_cmd_output(journal_cmd)
        if journal_status == 0:
            gather_cmd = ('isi_gather_info --local-only '
                          '-f %s/log/*' % mount_pt)
            subprocess.call(gather_cmd.split(), stdout=sys.stdout.fileno(),
                            stderr=sys.stdout.fileno())
        else:
            print("Blown journal not found in alternate /var partition.")

        # Unmount and remove mount point directory
        umount_cmd = 'umount %s' % mount_pt
        umount_status, umount_out = procs.get_cmd_output(umount_cmd)
        if umount_status == 0:
            try:
                os.rmdir(mount_pt)
            except OSError:
                print("Could not remove alternate /var mount point. Mount "
                      "point may not be unmounted.")
                sys.exit(1)
        else:
            print("Could not unmount alternate /var mount point "
                  "at %s." % mount_pt)
            sys.exit(1)
    else:
        print("ERROR: Could not determine which /var to mount, no "
              "gather initiated.")
        sys.exit(1)

if __name__ == "__main__":
    main()
