diff --git a/opennebula_api/models.py b/opennebula_api/models.py index 89a56774..7a8a333a 100644 --- a/opennebula_api/models.py +++ b/opennebula_api/models.py @@ -7,6 +7,7 @@ from oca.exceptions import OpenNebulaException from oca.pool import WrongNameError, WrongIdError from hosting.models import HostingOrder +from utils.cdist_utils import CdistUtilts from utils.models import CustomUser from utils.tasks import save_ssh_key from .exceptions import KeyExistsError, UserExistsError, UserCredentialError @@ -533,7 +534,7 @@ class OpenNebulaManager(): logger.debug( "VM with ID {} does not exist".format(order.vm_id)) if len(keys) > 0: - save_ssh_key.delay(hosts, keys) + save_ssh_key.delay(hosts, keys, CdistUtilts.get_cdist_index()) else: logger.debug("The user {} has no VMs. We don't need to configure " "the ssh keys.".format(self.email)) diff --git a/utils/cdist_utils.py b/utils/cdist_utils.py new file mode 100644 index 00000000..801a02d5 --- /dev/null +++ b/utils/cdist_utils.py @@ -0,0 +1,26 @@ +import cdist.integration as cdist_integration + + +class CdistUtilts(): + @staticmethod + def get_cdist_index(): + """ + Returns the next available instance index. + This is useful while making simultaneous configurations of + the same host. + :return: the next available index + """ + cdist_instance_index = cdist_integration.instance_index + cdist_index = next(cdist_instance_index) + return cdist_index + + @staticmethod + def free_cdist_index(cdist_index): + """ + Frees up the index that was used during configuring a host + using cdist. + :param cdist_index: The index to be freed + :return: + """ + cdist_instance_index = cdist_integration.instance_index + cdist_instance_index.free(cdist_index) diff --git a/utils/tasks.py b/utils/tasks.py index 6a246d54..d261ff31 100644 --- a/utils/tasks.py +++ b/utils/tasks.py @@ -1,12 +1,12 @@ -import tempfile - import cdist -import cdist.integration as cdist_integration +import tempfile +from cdist.integration import configure_hosts_simple from celery.utils.log import get_task_logger from django.conf import settings from django.core.mail import EmailMessage from dynamicweb.celery import app +from utils.cdist_utils import CdistUtilts logger = get_task_logger(__name__) @@ -26,7 +26,7 @@ def send_plain_email_task(self, email_data): @app.task(bind=True, max_retries=settings.CELERY_MAX_RETRIES) -def save_ssh_key(self, hosts, keys): +def save_ssh_key(self, hosts, keys, index): """ Saves ssh key into the VMs of a user using cdist @@ -36,8 +36,22 @@ def save_ssh_key(self, hosts, keys): 'value': 'sha-.....', # public key as string 'state': True # whether key is to be added or } # removed + :param index: An integer that uniquely identifies simultaneous cdist + configurations being run on a host """ + logger.debug("""Running save_ssh_key task for + Hosts: {hosts_str} + Keys: {keys_str} + index: {index}""".format(hosts_str=", ".join(hosts), + keys_str=", ".join([ + "{value}->{state}".format( + value=key.get('value'), + state=str( + key.get('state'))) + for key in keys]), + index=index) + ) return_value = True with tempfile.NamedTemporaryFile(delete=True) as tmp_manifest: # Generate manifest to be used for configuring the hosts @@ -51,14 +65,12 @@ def save_ssh_key(self, hosts, keys): tmp_manifest.writelines(lines_list) tmp_manifest.flush() try: - cdist_instance_index = cdist_integration.instance_index - cdist_index = next(cdist_instance_index) - cdist_integration.configure_hosts_simple(hosts, - tmp_manifest.name, - index=cdist_index, - verbose=cdist.argparse.VERBOSE_TRACE) - cdist_instance_index.free(cdist_index) + configure_hosts_simple(hosts, + tmp_manifest.name, + index=index, + verbose=cdist.argparse.VERBOSE_TRACE) except Exception as cdist_exception: logger.error(cdist_exception) return_value = False + CdistUtilts.free_cdist_index(index) return return_value