<commit_before># -*- coding: utf-8 -*-
#
# vmparking.py
#
# Copyright (C) 2010 <NAME> <<EMAIL>>
# This file is part of ArchipelProject
# http://archipelproject.org
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import datetime
import os
import shutil
import xmpp

from archipelcore.archipelPlugin import TNArchipelPlugin
from archipelcore.pubsub import TNPubSubNode
from archipelcore.utils import build_error_iq

ARCHIPEL_ERROR_CODE_VMPARK_LIST         = -11001
ARCHIPEL_ERROR_CODE_VMPARK_PARK         = -11002
ARCHIPEL_ERROR_CODE_VMPARK_UNPARK       = -11003
ARCHIPEL_ERROR_CODE_VMPARK_DELETE       = -11004
ARCHIPEL_ERROR_CODE_VMPARK_UPDATEXML    = -11004

ARCHIPEL_NS_VMPARKING = "archipel:hypervisor:vmparking"


class TNVMParking (TNArchipelPlugin):

    def __init__(self, configuration, entity, entry_point_group):
        """
        Initialize the plugin.
        @type configuration: Configuration object
        @param configuration: the configuration
        @type entity: L{TNArchipelEntity}
        @param entity: the entity that owns the plugin
        @type entry_point_group: string
        @param entry_point_group: the group name of plugin entry_point
        """
        TNArchipelPlugin.__init__(self, configuration=configuration, entity=entity, entry_point_group=entry_point_group)
        self.pubsub_vmparking = None;

        # creates permissions
        self.entity.permission_center.create_permission("vmparking_list", "Authorizes user to list virtual machines in parking", False)
        self.entity.permission_center.create_permission("vmparking_park", "Authorizes user to park a virtual machines", False)
        self.entity.permission_center.create_permission("vmparking_unpark", "Authorizes user to unpark a virtual machines", False)
        self.entity.permission_center.create_permission("vmparking_delete", "Authorizes user to delete parked virtual machines", False)
        self.entity.permission_center.create_permission("vmparking_updatexml", "Authorizes user to delete parked virtual machines", False)

        # register to the node vmrequest
        self.entity.register_hook("HOOK_ARCHIPELENTITY_XMPP_AUTHENTICATED", method=self.manage_vmparking_node)


    ### Plugin interface

    def register_handlers(self):
        """
        This method will be called by the plugin user when it will be
        necessary to register module for listening to stanza.
        """
        self.entity.xmppclient.RegisterHandler('iq', self.process_iq, ns=ARCHIPEL_NS_VMPARKING)

    def unregister_handlers(self):
        """
        Unregister the handlers.
        """
        self.entity.xmppclient.UnregisterHandler('iq', self.process_iq, ns=ARCHIPEL_NS_VMPARKING)

    @staticmethod
    def plugin_info():
        """
        Return informations about the plugin.
        @rtype: dict
        @return: dictionary contaning plugin informations
        """
        plugin_friendly_name           = "Virtual Machine Parking"
        plugin_identifier              = "vmparking"
        plugin_configuration_section   = None
        plugin_configuration_tokens    = []
        return {    "common-name"               : plugin_friendly_name,
                    "identifier"                : plugin_identifier,
                    "configuration-section"     : plugin_configuration_section,
                    "configuration-tokens"      : plugin_configuration_tokens }



    ### Pubsub management

    def manage_vmparking_node(self, origin, user_info, arguments):
        """
        Register to pubsub event node /archipel/platform/requests/in
        and /archipel/platform/requests/out
        @type origin: L{TNArchipelEnity}
        @param origin: the origin of the hook
        @type user_info: object
        @param user_info: random user information
        @type arguments: object
        @param arguments: runtime argument
        """
        nodeVMParkingName = "/archipel/vmparking"
        self.entity.log.info("VMPARKING: getting the pubsub node %s" % nodeVMParkingName)
        self.pubsub_vmparking = TNPubSubNode(self.entity.xmppclient, self.entity.pubsubserver, nodeVMParkingName)
        self.pubsub_vmparking.recover()
        self.entity.log.info("VMPARKING: node %s recovered." % nodeVMParkingName)
        self.pubsub_vmparking.subscribe(self.entity.jid.getStripped(), self._handle_request_event)
        self.entity.log.info("VMPARKING: entity %s is now subscribed to events from node %s" % (self.entity.jid, nodeVMParkingName))

    def _handle_request_event(self, event):
        """
        Triggered when a platform wide virtual machine request is received.
        @type event: xmpp.Node
        @param event: the push event
        """
        self.entity.log.debug("VMPARKING: received pubsub event")


    ### Processing function

    def is_vm_already_parked(self, uuid):
        """
        Check if vm with given UUID is already parked
        @type uuid: String
        @param uuid: the UUID of the vm
        @rtype: Boolean
        @return: True is vm is already in park
        """
        for n in self.pubsub_vmparking.get_items():
            if n.getTag("virtualmachine").getTag("domain").getTag("uuid").getData().lower() == uuid.lower():
                return True
        return False

    def list(self):
        """
        List virtual machines in the park. It returns a dict with the following form:<commit_msg>fix a problem in subscription to node /archipel/vmparking<commit_after># -*- coding: utf-8 -*-
#
# vmparking.py
#
# Copyright (C) 2010 <NAME> <<EMAIL>>
# This file is part of ArchipelProject
# http://archipelproject.org
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import datetime
import os
import shutil
import xmpp

from archipelcore.archipelPlugin import TNArchipelPlugin
from archipelcore.pubsub import TNPubSubNode
from archipelcore.utils import build_error_iq

ARCHIPEL_ERROR_CODE_VMPARK_LIST         = -11001
ARCHIPEL_ERROR_CODE_VMPARK_PARK         = -11002
ARCHIPEL_ERROR_CODE_VMPARK_UNPARK       = -11003
ARCHIPEL_ERROR_CODE_VMPARK_DELETE       = -11004
ARCHIPEL_ERROR_CODE_VMPARK_UPDATEXML    = -11004

ARCHIPEL_NS_VMPARKING = "archipel:hypervisor:vmparking"


class TNVMParking (TNArchipelPlugin):

    def __init__(self, configuration, entity, entry_point_group):
        """
        Initialize the plugin.
        @type configuration: Configuration object
        @param configuration: the configuration
        @type entity: L{TNArchipelEntity}
        @param entity: the entity that owns the plugin
        @type entry_point_group: string
        @param entry_point_group: the group name of plugin entry_point
        """
        TNArchipelPlugin.__init__(self, configuration=configuration, entity=entity, entry_point_group=entry_point_group)
        self.pubsub_vmparking = None;

        # creates permissions
        self.entity.permission_center.create_permission("vmparking_list", "Authorizes user to list virtual machines in parking", False)
        self.entity.permission_center.create_permission("vmparking_park", "Authorizes user to park a virtual machines", False)
        self.entity.permission_center.create_permission("vmparking_unpark", "Authorizes user to unpark a virtual machines", False)
        self.entity.permission_center.create_permission("vmparking_delete", "Authorizes user to delete parked virtual machines", False)
        self.entity.permission_center.create_permission("vmparking_updatexml", "Authorizes user to delete parked virtual machines", False)

        # register to the node vmrequest
        self.entity.register_hook("HOOK_ARCHIPELENTITY_XMPP_AUTHENTICATED", method=self.manage_vmparking_node)


    ### Plugin interface

    def register_handlers(self):
        """
        This method will be called by the plugin user when it will be
        necessary to register module for listening to stanza.
        """
        self.entity.xmppclient.RegisterHandler('iq', self.process_iq, ns=ARCHIPEL_NS_VMPARKING)

    def unregister_handlers(self):
        """
        Unregister the handlers.
        """
        self.entity.xmppclient.UnregisterHandler('iq', self.process_iq, ns=ARCHIPEL_NS_VMPARKING)

    @staticmethod
    def plugin_info():
        """
        Return informations about the plugin.
        @rtype: dict
        @return: dictionary contaning plugin informations
        """
        plugin_friendly_name           = "Virtual Machine Parking"
        plugin_identifier              = "vmparking"
        plugin_configuration_section   = None
        plugin_configuration_tokens    = []
        return {    "common-name"               : plugin_friendly_name,
                    "identifier"                : plugin_identifier,
                    "configuration-section"     : plugin_configuration_section,
                    "configuration-tokens"      : plugin_configuration_tokens }



    ### Pubsub management

    def manage_vmparking_node(self, origin, user_info, arguments):
        """
        Register to pubsub event node /archipel/platform/requests/in
        and /archipel/platform/requests/out
        @type origin: L{TNArchipelEnity}
        @param origin: the origin of the hook
        @type user_info: object
        @param user_info: random user information
        @type arguments: object
        @param arguments: runtime argument
        """
        nodeVMParkingName = "/archipel/vmparking"
        self.entity.log.info("VMPARKING: getting the pubsub node %s" % nodeVMParkingName)
        self.pubsub_vmparking = TNPubSubNode(self.entity.xmppclient, self.entity.pubsubserver, nodeVMParkingName)
        self.pubsub_vmparking.recover(wait=True)
        self.entity.log.info("VMPARKING: node %s recovered." % nodeVMParkingName)
        self.pubsub_vmparking.subscribe(self.entity.jid, self._handle_request_event, wait=True)
        self.entity.log.info("VMPARKING: entity %s is now subscribed to events from node %s" % (self.entity.jid, nodeVMParkingName))

    def _handle_request_event(self, event):
        """
        Triggered when a platform wide virtual machine request is received.
        @type event: xmpp.Node
        @param event: the push event
        """
        self.entity.log.debug("VMPARKING: received pubsub event")


    ### Processing function

    def is_vm_already_parked(self, uuid):
        """
        Check if vm with given UUID is already parked
        @type uuid: String
        @param uuid: the UUID of the vm
        @rtype: Boolean
        @return: True is vm is already in park
        """
        for n in self.pubsub_vmparking.get_items():
            if n.getTag("virtualmachine").getTag("domain").getTag("uuid").getData().lower() == uuid.lower():
                return True
        return False

    def list(self):
        """
        List virtual machines in the park. It returns a dict with the following form:
{'fraction_non_alphanumeric': 0.07842812137290665, 'fraction_numerical': 0.005140109434587962, 'mean_word_length': 3.021, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7323019', 'n_tokens_mistral': 3483, 'n_tokens_neox': 3359, 'n_words': 969}