import subprocess
import os
import time
from baseCheck import baseCheck

class checkMounts(baseCheck):

    def getHumanName(self):
            return "Check NAS mounts for each VM"

    def runCheck(self, config, debug):
        # do whatever is desired to check here.
        # return non-zero if an internal error is detected (equivilent to raising an exception)
        # return 0 for both check pass and check fail.
        #    call self.addWarning(text) or self.addWarning(rawText,humanText) for every warning to be logged
        #    call self.addFailure(text) or self.addFailure(rawText,humanText) for every failure to be logged

        # Get a list of auto-created NAS mounts provided through gluster fs
        nas = {}
        nascount = {}
        for server in config["environment"]["servers"]:
            for nasRequest in server["nasRequests"]:
                if nasRequest["size"] != '0':
                    name = nasRequest["name"]
                    size = int(nasRequest["size"])
                    if name in nas:
                        if nas[name] != size and len(nascount[name]) == 1:
                            self.addWarning("NAS mount %s should be the same size on %s and %s (%d GB != %d GB)." % (name,server["accessIP"],nascount[name][0],size,nas[name]))
                        nas[name] += size
                    else:
                        nas[name] = size
                        nascount[name] = []
                    nascount[name].append(server["accessIP"])

        # Print log messages and validate that no gluster mount spans > 2 hosts
        nasclusters = {}
        for mount in nas:
            self.logMsg("NAS mount %s has size %d GB." % (mount, nas[mount]))
            if len(nascount[mount]) > 2:
                self.addFailure("NAS mount %s is created across %d KVM hosts: %s.  Please restrict to at most 2 hosts." % (mount, len(nascount[mount]), ', '.join(nascount[mount])))
            elif len(nascount[mount]) == 2:
                if nascount[mount][0] < nascount[mount][1]:
                    pair = (nascount[mount][0],nascount[mount][1])
                else:
                    pair = (nascount[mount][1],nascount[mount][0])
                if not pair in nasclusters:
                    nasclusters[pair] = []
                nasclusters[pair].append(mount)

        # Now validate the clusters - no gluster host can share mounts with two different hosts
        problems = {}
        emptyserver = ''
        for server in config["environment"]["servers"]:
            peers = []
            singlemount = ''
            for cluster in nasclusters:
                if cluster[0] == server["accessIP"]:
                    peers.append(cluster[1])
                    if len(nasclusters[cluster]) == 1:
                        singlemount = nasclusters[cluster][0]
                if cluster[1] == server["accessIP"]:
                    peers.append(cluster[0])
                    if len(nasclusters[cluster]) == 1:
                        singlemount = nasclusters[cluster][0]
            if len(peers) == 0:
                emptyserver = server["accessIP"]
            elif len(peers) > 1:
                problems[server["accessIP"]] = (singlemount,peers)

        # Were any cluster errors detected?
        for mount in problems:
            if emptyserver != '':
                self.addFailure("NAS mount cluster error detected for KVM host %s [peers %s]. Recommend relocating NAS mount %s from %s to %s." % (mount, ",".join(problems[mount][1]), problems[mount][0], mount, emptyserver))
            else:
                self.addFailure("NAS mount cluster error detected for KVM host %s [peers %s]. Recommend relocating NAS mount %s from %s." % (mount, ",".join(problems[mount][1]), problems[mount][0], mount))

        # Make sure that each NAS mount on each VM is available through gluster fs
        for server in config["environment"]["servers"]:
            for vms in server["vms"]:
                for nasMounts in vms["nasMounts"]:
                    name = nasMounts["name"]
                    if name != '' and name not in nas:
                        self.addFailure("NAS mount %s is not available to VM %s.  Please verify Autocreated NAS configuration for each KVM host." % (name, vms["name"]))

        return 0
