#!/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.

# Version @VERSION@
#
# A plugin for executing script needed by vmops cloud 

import os, sys, time
import XenAPIPlugin
if os.path.exists("/opt/xensource/sm"):
    sys.path.extend(["/opt/xensource/sm/", "/usr/local/sbin/", "/sbin/"])
if os.path.exists("/usr/lib/xcp/sm"):
    sys.path.extend(["/usr/lib/xcp/sm/", "/usr/local/sbin/", "/sbin/"])

import SR, VDI, SRCommand, util, lvutil
from util import CommandException
import vhdutil
import shutil
import lvhdutil
import errno
import subprocess
import xs_errors
import cleanup
import stat
import random
import cloudstack_pluginlib as lib
import logging

lib.setup_logging("/var/log/cloud/cloud.log")

VHDUTIL = "vhd-util"
VHD_PREFIX = 'VHD-'
CLOUD_DIR = '/var/run/cloud_mount'

def echo(fn):
    def wrapped(*v, **k):
        name = fn.__name__
        logging.debug("#### CLOUD enter  %s ####" % name )
        res = fn(*v, **k)
        logging.debug("#### CLOUD exit  %s ####" % name )
        return res
    return wrapped


@echo
def create_secondary_storage_folder(session, args):
    local_mount_path = None

    logging.debug("create_secondary_storage_folder, args: " + str(args))

    try:
        try:
            # Mount the remote resource folder locally
            remote_mount_path = args["remoteMountPath"]
            local_mount_path = os.path.join(CLOUD_DIR, util.gen_uuid())
            mount(remote_mount_path, local_mount_path)

            # Create the new folder
            new_folder = local_mount_path + "/" + args["newFolder"]
            if not os.path.isdir(new_folder):
                current_umask = os.umask(0)
                os.makedirs(new_folder)
                os.umask(current_umask)
        except OSError, (errno, strerror):
            errMsg = "create_secondary_storage_folder failed: errno: " + str(errno) + ", strerr: " + strerror
            logging.debug(errMsg)
            raise xs_errors.XenError(errMsg)
        except:
            errMsg = "create_secondary_storage_folder failed."
            logging.debug(errMsg)
            raise xs_errors.XenError(errMsg)
    finally:
        if local_mount_path != None:
            # Unmount the local folder
            umount(local_mount_path)
            # Remove the local folder
            os.system("rmdir " + local_mount_path)
        
    return "1"

@echo
def delete_secondary_storage_folder(session, args):
    local_mount_path = None

    logging.debug("delete_secondary_storage_folder, args: " + str(args))

    try:
        try:
            # Mount the remote resource folder locally
            remote_mount_path = args["remoteMountPath"]
            local_mount_path = os.path.join(CLOUD_DIR, util.gen_uuid())
            mount(remote_mount_path, local_mount_path)

            # Delete the specified folder
            folder = local_mount_path + "/" + args["folder"]
            if os.path.isdir(folder):
                os.system("rm -f " + folder + "/*")
                os.system("rmdir " + folder)
        except OSError, (errno, strerror):
            errMsg = "delete_secondary_storage_folder failed: errno: " + str(errno) + ", strerr: " + strerror
            logging.debug(errMsg)
            raise xs_errors.XenError(errMsg)
        except:
            errMsg = "delete_secondary_storage_folder failed."
            logging.debug(errMsg)
            raise xs_errors.XenError(errMsg)
    finally:
        if local_mount_path != None:
            # Unmount the local folder
            umount(local_mount_path)
            # Remove the local folder
            os.system("rmdir " + local_mount_path)
        
    return "1"
     
@echo
def post_create_private_template(session, args):
    local_mount_path = None
    try:
        try:
            # get local template folder 
            templatePath = args["templatePath"]
            local_mount_path = os.path.join(CLOUD_DIR, util.gen_uuid())
            mount(templatePath, local_mount_path)
            # Retrieve args
            filename = args["templateFilename"]
            name = args["templateName"]
            description = args["templateDescription"]
            checksum = args["checksum"]
            file_size = args["size"]
            virtual_size = args["virtualSize"]
            template_id = args["templateId"]
           
            # Create the template.properties file
            template_properties_install_path = local_mount_path + "/template.properties"
            f = open(template_properties_install_path, "w")
            f.write("filename=" + filename + "\n")
            f.write("vhd=true\n")
            f.write("id=" + template_id + "\n")
            f.write("vhd.filename=" + filename + "\n")
            f.write("public=false\n")
            f.write("uniquename=" + name + "\n")
            f.write("vhd.virtualsize=" + virtual_size + "\n")
            f.write("virtualsize=" + virtual_size + "\n")
            f.write("checksum=" + checksum + "\n")
            f.write("hvm=true\n")
            f.write("description=" + description + "\n")
            f.write("vhd.size=" + str(file_size) + "\n")
            f.write("size=" + str(file_size) + "\n")
            f.close()
            logging.debug("Created template.properties file")
           
            # Set permissions
            permissions = stat.S_IREAD | stat.S_IWRITE | stat.S_IRGRP | stat.S_IWGRP | stat.S_IROTH | stat.S_IWOTH
            os.chmod(template_properties_install_path, permissions)
            logging.debug("Set permissions on template and template.properties")

        except:
            errMsg = "post_create_private_template failed."
            logging.debug(errMsg)
            raise xs_errors.XenError(errMsg)

    finally:
        if local_mount_path != None:
            # Unmount the local folder
            umount(local_mount_path)
            # Remove the local folder
            os.system("rmdir " + local_mount_path)
    return "1" 
  
def isfile(path, isISCSI):
    errMsg = ''
    exists = True
    if isISCSI:
        exists = checkVolumeAvailablility(path)
    else:
        exists = os.path.isfile(path)
        
    if not exists:
        errMsg = "File " + path + " does not exist."
        logging.debug(errMsg)
        raise xs_errors.XenError(errMsg)
    return errMsg

def copyfile(fromFile, toFile, isISCSI):
    logging.debug("Starting to copy " + fromFile + " to " + toFile)
    errMsg = ''
    if isISCSI:
        bs = "4M"
    else:
        bs = "128k"

    try:
        cmd = ['dd', 'if=' + fromFile, 'iflag=direct', 'of=' + toFile, 'oflag=direct', 'bs=' + bs]
        txt = util.pread2(cmd)
    except:
        try:
            os.system("rm -f " + toFile)
        except:
            txt = ''
        txt = ''
        errMsg = "Error while copying " + fromFile + " to " + toFile + " in secondary storage"
        logging.debug(errMsg)
        raise xs_errors.XenError(errMsg)

    logging.debug("Successfully copied " + fromFile + " to " + toFile)
    return errMsg

def chdir(path):
    try:
        os.chdir(path)
    except OSError, (errno, strerror):
        errMsg = "Unable to chdir to " + path + " because of OSError with errno: " + str(errno) + " and strerr: " + strerror
        logging.debug(errMsg)
        raise xs_errors.XenError(errMsg)
    logging.debug("Chdired to " + path)
    return

def scanParent(path):
    # Do a scan for the parent for ISCSI volumes
    # Note that the parent need not be visible on the XenServer
    parentUUID = ''
    try:
        lvName = os.path.basename(path)
        dirname = os.path.dirname(path)
        vgName = os.path.basename(dirname) 
        vhdInfo = vhdutil.getVHDInfoLVM(lvName, lvhdutil.extractUuid, vgName)
        parentUUID = vhdInfo.parentUuid
    except:
        errMsg = "Could not get vhd parent of " + path
        logging.debug(errMsg)
        raise xs_errors.XenError(errMsg)
    return parentUUID

def getParent(path, isISCSI):
    parentUUID = ''
    try :
        if isISCSI:
            parentUUID = vhdutil.getParent(path, lvhdutil.extractUuid)
        else:
            parentUUID = vhdutil.getParent(path, cleanup.FileVDI.extractUuid)
    except:
        errMsg = "Could not get vhd parent of " + path
        logging.debug(errMsg)
        raise xs_errors.XenError(errMsg)
    return parentUUID

def getParentOfSnapshot(snapshotUuid, primarySRPath, isISCSI):
    snapshotVHD    = getVHD(snapshotUuid, isISCSI)
    snapshotPath   = os.path.join(primarySRPath, snapshotVHD)

    baseCopyUuid = ''
    if isISCSI:
        checkVolumeAvailablility(snapshotPath)
        baseCopyUuid = scanParent(snapshotPath)
    else:
        baseCopyUuid = getParent(snapshotPath, isISCSI)
    
    logging.debug("Base copy of snapshotUuid: " + snapshotUuid + " is " + baseCopyUuid)
    return baseCopyUuid

def setParent(parent, child):
    try:
        cmd = [VHDUTIL, "modify", "-p", parent, "-n", child]
        txt = util.pread2(cmd)
    except:
        errMsg = "Unexpected error while trying to set parent of " + child + " to " + parent 
        logging.debug(errMsg)
        raise xs_errors.XenError(errMsg)
    logging.debug("Successfully set parent of " + child + " to " + parent)
    return

def rename(originalVHD, newVHD):
    try:
        os.rename(originalVHD, newVHD)
    except OSError, (errno, strerror):
        errMsg = "OSError while renaming " + origiinalVHD + " to " + newVHD + "with errno: " + str(errno) + " and strerr: " + strerror
        logging.debug(errMsg)
        raise xs_errors.XenError(errMsg)
    return

def makedirs(path):
    if not os.path.isdir(path):
        try:
            os.makedirs(path)
        except OSError, (errno, strerror):
            umount(path)
            if os.path.isdir(path):
                return
            errMsg = "OSError while creating " + path + " with errno: " + str(errno) + " and strerr: " + strerror
            logging.debug(errMsg)
            raise xs_errors.XenError(errMsg)
    return

def mount(remoteDir, localDir):
    makedirs(localDir)
    options = "soft,tcp,timeo=133,retrans=1"
    try: 
        cmd = ['mount', '-o', options, remoteDir, localDir]
        txt = util.pread2(cmd)
    except:
        txt = ''
        errMsg = "Unexpected error while trying to mount " + remoteDir + " to " + localDir 
        logging.debug(errMsg)
        raise xs_errors.XenError(errMsg)
    logging.debug("Successfully mounted " + remoteDir + " to " + localDir)

    return

def umount(localDir):
    try: 
        cmd = ['umount', localDir]
        util.pread2(cmd)
    except CommandException:
        errMsg = "CommandException raised while trying to umount " + localDir 
        logging.debug(errMsg)
        raise xs_errors.XenError(errMsg)

    logging.debug("Successfully unmounted " + localDir)
    return

def mountSnapshotsDir(secondaryStorageMountPath, localMountPointPath, path):
    # The aim is to mount secondaryStorageMountPath on 
    # And create <accountId>/<instanceId> dir on it, if it doesn't exist already.
    # Assuming that secondaryStorageMountPath  exists remotely

    # Just mount secondaryStorageMountPath/<relativeDir>/SecondaryStorageHost/ everytime
    # Never unmount.
    # path is like "snapshots/account/volumeId", we mount secondary_storage:/snapshots
    relativeDir = path.split("/")[0]
    restDir = "/".join(path.split("/")[1:])
    snapshotsDir = os.path.join(secondaryStorageMountPath, relativeDir)

    makedirs(localMountPointPath)
    # if something is not mounted already on localMountPointPath,
    # mount secondaryStorageMountPath on localMountPath
    if os.path.ismount(localMountPointPath):
        # There is more than one secondary storage per zone.
        # And we are mounting each sec storage under a zone-specific directory
        # So two secondary storage snapshot dirs will never get mounted on the same point on the same XenServer.
        logging.debug("The remote snapshots directory has already been mounted on " + localMountPointPath)
    else:
        mount(snapshotsDir, localMountPointPath)

    # Create accountId/instanceId dir on localMountPointPath, if it doesn't exist
    backupsDir = os.path.join(localMountPointPath, restDir)
    makedirs(backupsDir)
    return backupsDir

def unmountAll(path):
    try:
        for dir in os.listdir(path):
            if dir.isdigit():
                logging.debug("Unmounting Sub-Directory: " + dir)
                localMountPointPath = os.path.join(path, dir)
                umount(localMountPointPath)
    except:
        logging.debug("Ignoring the error while trying to unmount the snapshots dir")

@echo
def unmountSnapshotsDir(session, args):
    dcId = args['dcId']
    localMountPointPath = os.path.join(CLOUD_DIR, dcId)
    localMountPointPath = os.path.join(localMountPointPath, "snapshots")
    unmountAll(localMountPointPath)
    try:
        umount(localMountPointPath)
    except:
        logging.debug("Ignoring the error while trying to unmount the snapshots dir.")

    return "1"

def getPrimarySRPath(primaryStorageSRUuid, isISCSI):
    if isISCSI:
        primarySRDir = lvhdutil.VG_PREFIX + primaryStorageSRUuid
        return os.path.join(lvhdutil.VG_LOCATION, primarySRDir)
    else:
        return os.path.join(SR.MOUNT_BASE, primaryStorageSRUuid)

def getBackupVHD(UUID):
    return UUID + '.' + SR.DEFAULT_TAP

def getVHD(UUID, isISCSI):
    if isISCSI:
        return VHD_PREFIX + UUID
    else:
        return UUID + '.' + SR.DEFAULT_TAP

def getIsTrueString(stringValue):
    booleanValue = False
    if (stringValue and stringValue == 'true'):
        booleanValue = True
    return booleanValue 

def makeUnavailable(uuid, primarySRPath, isISCSI):
    if not isISCSI:
        return
    VHD = getVHD(uuid, isISCSI)
    path = os.path.join(primarySRPath, VHD)
    manageAvailability(path, '-an')
    return

def manageAvailability(path, value):
    if path.__contains__("/var/run/sr-mount"):
        return
    logging.debug("Setting availability of " + path + " to " + value)
    try:
        cmd = ['/usr/sbin/lvchange', value, path]
        util.pread2(cmd)
    except: #CommandException, (rc, cmdListStr, stderr):
        #errMsg = "CommandException thrown while executing: " + cmdListStr + " with return code: " + str(rc) + " and stderr: " + stderr
        errMsg = "Unexpected exception thrown by lvchange"
        logging.debug(errMsg)
        if value == "-ay":
            # Raise an error only if we are trying to make it available.
            # Just warn if we are trying to make it unavailable after the 
            # snapshot operation is done.
            raise xs_errors.XenError(errMsg)
    return


def checkVolumeAvailablility(path):
    try:
        if not isVolumeAvailable(path):
            # The VHD file is not available on XenSever. The volume is probably
            # inactive or detached.
            # Do lvchange -ay to make it available on XenServer
            manageAvailability(path, '-ay')
    except:
        errMsg = "Could not determine status of ISCSI path: " + path
        logging.debug(errMsg)
        raise xs_errors.XenError(errMsg)
    
    success = False
    i = 0
    while i < 6:
        i = i + 1
        # Check if the vhd is actually visible by checking for the link
        # set isISCSI to true
        success = isVolumeAvailable(path)
        if success:
            logging.debug("Made vhd: " + path + " available and confirmed that it is visible")
            break

        # Sleep for 10 seconds before checking again.
        time.sleep(10)

    # If not visible within 1 min fail
    if not success:
        logging.debug("Could not make vhd: " +  path + " available despite waiting for 1 minute. Does it exist?")

    return success

def isVolumeAvailable(path):
    # Check if iscsi volume is available on this XenServer.
    status = "0"
    try:
        p = subprocess.Popen(["/bin/bash", "-c", "if [ -L " + path + " ]; then echo 1; else echo 0;fi"], stdout=subprocess.PIPE)
        status = p.communicate()[0].strip("\n")
    except:
        errMsg = "Could not determine status of ISCSI path: " + path
        logging.debug(errMsg)
        raise xs_errors.XenError(errMsg)

    return (status == "1")  

def getVhdParent(session, args):
    logging.debug("getParent with " + str(args))
    primaryStorageSRUuid      = args['primaryStorageSRUuid']
    snapshotUuid              = args['snapshotUuid']
    isISCSI                   = getIsTrueString(args['isISCSI']) 

    primarySRPath = getPrimarySRPath(primaryStorageSRUuid, isISCSI)
    logging.debug("primarySRPath: " + primarySRPath)

    baseCopyUuid = getParentOfSnapshot(snapshotUuid, primarySRPath, isISCSI)

    return  baseCopyUuid

def getSnapshotSize(session, args):
    primaryStorageSRUuid      = args['primaryStorageSRUuid']
    snapshotUuid              = args['snapshotUuid']
    isISCSI                   = getIsTrueString(args['isISCSI'])

    primarySRPath = getPrimarySRPath(primaryStorageSRUuid, isISCSI)
    logging.debug("primarySRPath: " + primarySRPath)

    snapshotVHD  = getVHD(snapshotUuid, isISCSI)
    snapshotPath = os.path.join(primarySRPath, snapshotVHD)
    physicalSize = vhdutil.getSizePhys(snapshotPath)
    return str(physicalSize)

def backupSnapshot(session, args):
    logging.debug("Called backupSnapshot with " + str(args))
    primaryStorageSRUuid      = args['primaryStorageSRUuid']
    secondaryStorageMountPath = args['secondaryStorageMountPath']
    snapshotUuid              = args['snapshotUuid']
    prevBackupUuid            = args['prevBackupUuid']
    backupUuid                = args['backupUuid']
    isISCSI                   = getIsTrueString(args['isISCSI'])
    path = args['path']
    localMountPoint = args['localMountPoint']
    primarySRPath = getPrimarySRPath(primaryStorageSRUuid, isISCSI)
    logging.debug("primarySRPath: " + primarySRPath)

    baseCopyUuid = getParentOfSnapshot(snapshotUuid, primarySRPath, isISCSI)
    baseCopyVHD  = getVHD(baseCopyUuid, isISCSI)
    baseCopyPath = os.path.join(primarySRPath, baseCopyVHD)
    logging.debug("Base copy path: " + baseCopyPath)


    # Mount secondary storage mount path on XenServer along the path
    # /var/run/sr-mount/<dcId>/snapshots/ and create <accountId>/<volumeId> dir
    # on it.
    backupsDir = mountSnapshotsDir(secondaryStorageMountPath, localMountPoint, path)
    logging.debug("Backups dir " + backupsDir)
    prevBackupUuid = prevBackupUuid.split("/")[-1]
    # Check existence of snapshot on primary storage
    isfile(baseCopyPath, isISCSI)
    physicalSize = vhdutil.getSizePhys(baseCopyPath)
    if prevBackupUuid:
        # Check existence of prevBackupFile
        prevBackupVHD = getBackupVHD(prevBackupUuid)
        prevBackupFile = os.path.join(backupsDir, prevBackupVHD)
        isfile(prevBackupFile, False)

    # copy baseCopyPath to backupsDir with new uuid
    backupVHD = getBackupVHD(backupUuid)  
    backupFile = os.path.join(backupsDir, backupVHD)
    logging.debug("Back up " + baseCopyUuid + " to Secondary Storage as " + backupUuid)
    copyfile(baseCopyPath, backupFile, isISCSI)
    vhdutil.setHidden(backupFile, False)

    # Because the primary storage is always scanned, the parent of this base copy is always the first base copy.
    # We don't want that, we want a chain of VHDs each of which is a delta from the previous.
    # So set the parent of the current baseCopyVHD to prevBackupVHD 
    if prevBackupUuid:
        # If there was a previous snapshot
        setParent(prevBackupFile, backupFile)

    txt = "1#" + backupUuid + "#" + str(physicalSize)
    return txt

@echo
def deleteSnapshotBackup(session, args):
    logging.debug("Calling deleteSnapshotBackup with " + str(args))
    secondaryStorageMountPath = args['secondaryStorageMountPath']
    backupUUID                = args['backupUUID']
    path = args['path']
    localMountPoint = args['localMountPoint']

    backupsDir = mountSnapshotsDir(secondaryStorageMountPath, localMountPoint, path)
    # chdir to the backupsDir for convenience
    chdir(backupsDir)

    backupVHD = getBackupVHD(backupUUID)
    logging.debug("checking existence of " + backupVHD)

    # The backupVHD is on secondary which is NFS and not ISCSI.
    if not os.path.isfile(backupVHD):
        logging.debug("backupVHD " + backupVHD + "does not exist. Not trying to delete it")
        return "1"
    logging.debug("backupVHD " + backupVHD + " exists.")
        
    # Just delete the backupVHD
    try:
        os.remove(backupVHD)
    except OSError, (errno, strerror):
        errMsg = "OSError while removing " + backupVHD + " with errno: " + str(errno) + " and strerr: " + strerror
        logging.debug(errMsg)
        raise xs_errors.XenError(errMsg)

    return "1"
   
@echo
def revert_memory_snapshot(session, args):
    logging.debug("Calling revert_memory_snapshot with " + str(args))
    vmName = args['vmName']
    snapshotUUID = args['snapshotUUID']
    oldVmUuid = args['oldVmUuid']
    snapshotMemory = args['snapshotMemory']
    hostUUID = args['hostUUID']
    try:
        cmd = '''xe vbd-list vm-uuid=%s | grep 'vdi-uuid' | grep -v 'not in database' | sed -e 's/vdi-uuid ( RO)://g' ''' % oldVmUuid
        vdiUuids = os.popen(cmd).read().split()
        cmd2 = '''xe vm-param-get param-name=power-state uuid=''' + oldVmUuid
        if os.popen(cmd2).read().split()[0] != 'halted':
            os.system("xe vm-shutdown force=true vm=" + vmName)
        os.system("xe vm-destroy uuid=" + oldVmUuid)
        os.system("xe snapshot-revert snapshot-uuid=" + snapshotUUID)
        if snapshotMemory == 'true':
            os.system("xe vm-resume vm=" + vmName + " on=" + hostUUID)
        for vdiUuid in vdiUuids:
            os.system("xe vdi-destroy uuid=" + vdiUuid)
    except OSError, (errno, strerror):
        errMsg = "OSError while reverting vm " + vmName + " to snapshot " + snapshotUUID + " with errno: " + str(errno) + " and strerr: " + strerror
        logging.debug(errMsg)
        raise xs_errors.XenError(errMsg)
    return "0"

if __name__ == "__main__":
    XenAPIPlugin.dispatch({"getVhdParent":getVhdParent,  "create_secondary_storage_folder":create_secondary_storage_folder, "delete_secondary_storage_folder":delete_secondary_storage_folder, "post_create_private_template":post_create_private_template, "backupSnapshot": backupSnapshot, "deleteSnapshotBackup": deleteSnapshotBackup, "unmountSnapshotsDir": unmountSnapshotsDir, "revert_memory_snapshot":revert_memory_snapshot, "getSnapshotSize":getSnapshotSize})
    

