#!/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, relativeDir, dcId, accountId, instanceId):
    # 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

    # Alex's suggestion and currently implemented:
    # Just mount secondaryStorageMountPath/<relativeDir> everytime
    # Never unmount.
    snapshotsDir = os.path.join(secondaryStorageMountPath, relativeDir)

    # Mkdir local mount point dir, if it doesn't exist.
    localMountPointPath = os.path.join(CLOUD_DIR, dcId)
    localMountPointPath = os.path.join(localMountPointPath, relativeDir)

    makedirs(localMountPointPath)
    # if something is not mounted already on localMountPointPath, 
    # mount secondaryStorageMountPath on localMountPath
    if os.path.ismount(localMountPointPath):
        # There is only 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, accountId)
    backupsDir = os.path.join(backupsDir, instanceId)
    makedirs(backupsDir)
    return backupsDir

@echo
def unmountSnapshotsDir(session, args):
    dcId = args['dcId']
    localMountPointPath = os.path.join(CLOUD_DIR, dcId)
    localMountPointPath = os.path.join(localMountPointPath, "snapshots")
    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']
    dcId                      = args['dcId']
    accountId                 = args['accountId']
    volumeId                  = args['volumeId']
    secondaryStorageMountPath = args['secondaryStorageMountPath']
    snapshotUuid              = args['snapshotUuid']
    prevBackupUuid            = args['prevBackupUuid']
    backupUuid                = args['backupUuid']
    isISCSI                   = getIsTrueString(args['isISCSI']) 

    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, "snapshots", dcId, accountId, volumeId)
    util.SMlog("Backups dir " + backupsDir)

    # 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))
    dcId                      = args['dcId']
    accountId                 = args['accountId']
    volumeId                  = args['volumeId']
    secondaryStorageMountPath = args['secondaryStorageMountPath']
    backupUUID                = args['backupUUID']

    backupsDir = mountSnapshotsDir(secondaryStorageMountPath, "snapshots", dcId, accountId, volumeId)
    # 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})
    

