#!/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
sys.path.append("/opt/xensource/sm/")
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

VHD_UTIL = '/opt/xensource/bin/vhd-util'
VHD_PREFIX = 'VHD-'
CLOUD_DIR = '/var/run/cloud_mount'

def echo(fn):
    def wrapped(*v, **k):
        name = fn.__name__
        util.SMlog("#### VMOPS enter  %s ####" % name )
        res = fn(*v, **k)
        util.SMlog("#### VMOPS exit  %s ####" % name )
        return res
    return wrapped


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

    util.SMlog("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
            util.SMlog(errMsg)
            raise xs_errors.XenError(errMsg)
        except:
            errMsg = "create_secondary_storage_folder failed."
            util.SMlog(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

    util.SMlog("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
            util.SMlog(errMsg)
            raise xs_errors.XenError(errMsg)
        except:
            errMsg = "delete_secondary_storage_folder failed."
            util.SMlog(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()
            util.SMlog("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)
            util.SMlog("Set permissions on template and template.properties")

        except:
            errMsg = "post_create_private_template failed."
            util.SMlog(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."
        util.SMlog(errMsg)
        raise xs_errors.XenError(errMsg)
    return errMsg

def copyfile(fromFile, toFile, isISCSI):
    util.SMlog("Starting to copy " + fromFile + " to " + toFile)
    errMsg = ''
    try:
        cmd = ['dd', 'if=' + fromFile, 'of=' + toFile, 'bs=4M']
        txt = util.pread2(cmd)
    except:
        try:
            os.system("rm -f " + toFile)
        except:
            txt = ''
        txt = ''
        errMsg = "Error while copying " + fromFile + " to " + toFile + " in secondary storage"
        util.SMlog(errMsg)
        raise xs_errors.XenError(errMsg)

    util.SMlog("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
        util.SMlog(errMsg)
        raise xs_errors.XenError(errMsg)
    util.SMlog("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
        util.SMlog(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
        util.SMlog(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)
    
    util.SMlog("Base copy of snapshotUuid: " + snapshotUuid + " is " + baseCopyUuid)
    return baseCopyUuid

def setParent(parent, child):
    try:
        cmd = [VHD_UTIL, "modify", "-p", parent, "-n", child]
        txt = util.pread2(cmd)
    except:
        errMsg = "Unexpected error while trying to set parent of " + child + " to " + parent 
        util.SMlog(errMsg)
        raise xs_errors.XenError(errMsg)
    util.SMlog("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
        util.SMlog(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
            util.SMlog(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 
        util.SMlog(errMsg)
        raise xs_errors.XenError(errMsg)
    util.SMlog("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 
        util.SMlog(errMsg)
        raise xs_errors.XenError(errMsg)

    util.SMlog("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.
        util.SMlog("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():
                util.SMlog("Unmounting Sub-Directory: " + dir)
                localMountPointPath = os.path.join(path, dir)
                umount(localMountPointPath)
    except:
        util.SMlog("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:
        util.SMlog("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
    util.SMlog("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"
        util.SMlog(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
        util.SMlog(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:
            util.SMlog("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:
        util.SMlog("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
        util.SMlog(errMsg)
        raise xs_errors.XenError(errMsg)

    return (status == "1")  

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

    primarySRPath = getPrimarySRPath(primaryStorageSRUuid, isISCSI)
    util.SMlog("primarySRPath: " + primarySRPath)

    baseCopyUuid = getParentOfSnapshot(snapshotUuid, primarySRPath, isISCSI)

    return  baseCopyUuid


def backupSnapshot(session, args):
    util.SMlog("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)
    util.SMlog("primarySRPath: " + primarySRPath)

    baseCopyUuid = getParentOfSnapshot(snapshotUuid, primarySRPath, isISCSI)
    baseCopyVHD  = getVHD(baseCopyUuid, isISCSI)
    baseCopyPath = os.path.join(primarySRPath, baseCopyVHD)
    util.SMlog("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)
    util.SMlog("Backups dir " + backupsDir)
    prevBackupUuid = prevBackupUuid.split("/")[-1]
    # Check existence of snapshot on primary storage
    isfile(baseCopyPath, isISCSI)
    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)
    util.SMlog("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
    return txt

@echo
def deleteSnapshotBackup(session, args):
    util.SMlog("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)
    util.SMlog("checking existence of " + backupVHD)

    # The backupVHD is on secondary which is NFS and not ISCSI.
    if not os.path.isfile(backupVHD):
        util.SMlog("backupVHD " + backupVHD + "does not exist. Not trying to delete it")
        return "1"
    util.SMlog("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
        util.SMlog(errMsg)
        raise xs_errors.XenError(errMsg)

    return "1"
   
@echo
def revert_memory_snapshot(session, args):
    util.SMlog("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
        util.SMlog(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})
    

