#!/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, secHostId):
    # 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.
    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, secHostId)

    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, accountId)
    backupsDir = os.path.join(backupsDir, instanceId)
    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']
    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'])
    secHostId                 = args['secHostId']

    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, secHostId)
    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})
    

