#!/usr/bin/python
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

import sys, os
from subprocess import PIPE, Popen
import logging
import traceback
from os.path import exists, join
from signal import alarm, signal, SIGALRM, SIGKILL

class CloudRuntimeException(Exception):
    def __init__(self, errMsg):
        self.errMsg = errMsg
    def __str__(self):
        return self.errMsg
def formatExceptionInfo(maxTBlevel=5):
    cla, exc, trbk = sys.exc_info()
    excTb = traceback.format_tb(trbk, maxTBlevel)
    msg = str(exc) + "\n"
    for tb in excTb:
        msg += tb
    return msg

class bash:
    def __init__(self, args, timeout=600):
        self.args = args
        logging.debug("execute:%s"%args)
        self.timeout = timeout
        self.process = None
        self.success = False
        self.run()

    def run(self):
        class Alarm(Exception):
            pass
        def alarm_handler(signum, frame):
            raise Alarm

        try:
            self.process = Popen(self.args, shell=True, stdout=PIPE, stderr=PIPE)
            if self.timeout != -1:
                signal(SIGALRM, alarm_handler)
                alarm(self.timeout)

            try:
                self.stdout, self.stderr = self.process.communicate()
                if self.timeout != -1:
                    alarm(0)
            except Alarm:
                os.kill(self.process.pid, SIGKILL)
                raise  CloudRuntimeException("Timeout during command execution")

            self.success = self.process.returncode == 0
        except:
            raise  CloudRuntimeException(formatExceptionInfo())

#        if not self.success:
#            raise  CloudRuntimeException(self.getStderr())

    def isSuccess(self):
        return self.success

    def getStdout(self):
        return self.stdout.strip("\n")

    def getLines(self):
        return self.stdout.split("\n")

    def getStderr(self):
        return self.stderr.strip("\n")


def initLoging(logFile=None):
    try:
        if logFile is None:
            logging.basicConfig(level=logging.DEBUG)
        else:
            logging.basicConfig(filename=logFile, level=logging.DEBUG)
    except:
        logging.basicConfig(level=logging.DEBUG)

def writeProgressBar(msg, result=None):
    if msg is not None:
        output = "%-80s"%msg
    elif result is True:
        output = "[ \033[92m%-2s\033[0m ]\n"%"OK"
    elif result is False:
        output = "[ \033[91m%-6s\033[0m ]\n"%"FAILED"
    sys.stdout.write(output)
    sys.stdout.flush()

def printError(msg):
    sys.stderr.write(msg)
    sys.stderr.write("\n")
    sys.stderr.flush()

def printMsg(msg):
    sys.stdout.write(msg+"\n")
    sys.stdout.flush()

def checkRpm(pkgName):
    chkPkg = bash("rpm -q %s"%pkgName)
    writeProgressBar("Checking %s"%pkgName, None)
    if not chkPkg.isSuccess():
        writeProgressBar(None, False)
        printError("%s is not found, please make sure it is installed. You may try 'yum install %s'\n"%(pkgName, pkgName))
        return False
    else:
        writeProgressBar(None, True)
        return True

def checkEnv():
   writeProgressBar("Checking is root")
   ret = bash("whoami")
   if ret.getStdout() != "root":
       writeProgressBar(None, False)
       printError("This script must run as root")
       return False
   else:
       writeProgressBar(None, True)

   pkgList = ['tftp-server', 'syslinux', 'xinetd', 'chkconfig', 'dhcp']
   for pkg in pkgList:
       if not checkRpm(pkg):
           return False
   return True

def exitIfFail(ret):
    if not ret: sys.exit(1)

def bashWithResult(cmd):
    writeProgressBar("Executing '%s'"%cmd)
    ret = bash(cmd)
    if not ret.isSuccess():
        writeProgressBar(None, False)
        writeProgressBar(ret.getStderr() + '\n')
        return False
    else:
        writeProgressBar(None, True)
        return True

def configurePxeStuff():
    stuff = ['tftp', 'xinetd', 'dhcpd']
    cmds = ['chkconfig --level 345 %s on' % i for i in stuff]
    cmds.append('/etc/init.d/xinetd restart')

    for cmd in cmds:
        if not bashWithResult(cmd): return False

    chkIptable = bash('chkconfig --list iptables')
    if 'on' in chkIptable.getStdout():
        printMsg("Detected iptables is running, need to open tftp port 69")
        if not bashWithResult('iptables -I INPUT 1 -p udp --dport 69 -j ACCEPT'): return False
        if not bashWithResult('/etc/init.d/iptables save'): return False

    return True

def getTftpRootDir(tftpRootDirList):
    tftpRoot = bash("cat /etc/xinetd.d/tftp | grep server_args")
    if not tftpRoot.isSuccess():
        printError("Cannot get tftp root directory from /etc/xinetd.d/tftp, here may be something wrong with your tftp-server, try reinstall it\n")
        return False
    tftpRootDir = tftpRoot.getStdout()
    index = tftpRootDir.find("/")
    if index == -1:
        printError("Wrong server_arg in /etc/xinetd.d/tftp (%s)"%tftpRootDir)
        return False
    tftpRootDir = tftpRootDir[index:]
    tftpRootDirList.append(tftpRootDir)
    return True

def preparePING(tftpRootDir):
    pingFiles = ['boot.msg', 'initrd.gz', 'kernel', 'pxelinux.0']
    pingDir = "/usr/share/PING"

    for f in pingFiles:
        path = join(pingDir, f)
        if not exists(path):
            printError("Cannot find %s, please make sure PING-3.01 is installed"%path)
            return False
        if not bashWithResult("cp -f %s %s"%(path, tftpRootDir)): return False

    if not bashWithResult("mkdir -p %s/pxelinux.cfg"%tftpRootDir): return False

    return True

def prepareSyslinux(tftpRootDir):
    pkg = '/usr/share/syslinux/pxelinux.0'
    if not os.path.exists(pkg):
        printError('cannot find pxelinux.0 on system. is syslinux installed?')
        return False

    cp = "cp -f %s %s" % (pkg, tftpRootDir)
    if not bashWithResult(cp):
        return False

    return True



if __name__ == "__main__":
    initLoging("/tmp/cloud-setup-baremetal.log")
    tftpRootDirList = []

    exitIfFail(checkEnv())
    exitIfFail(configurePxeStuff())
    exitIfFail(getTftpRootDir(tftpRootDirList))

    tftpRootDir = tftpRootDirList[0].strip()
    #exitIfFail(preparePING(tftpRootDir))
    exitIfFail(prepareSyslinux(tftpRootDir))
    printMsg("")
    printMsg("Setup BareMetal PXE server successfully")
    printMsg("TFTP root directory is: %s\n"%tftpRootDir)
    sys.exit(0)
