def set_state_task_for_instance(ctx, graph, node_id, instance, state_name, step_id):
    #ctx.internal.send_workflow_event(
    #        event_type='other',
    #        message="call: set_state_task_for_instance(node_id: {0}, state_name: {1}, step_id: {2}, instance: {3})".format(node_id, state_name, step_id, instance))
    task = TaskSequenceWrapper(graph)
    task.add(build_wf_event_task(instance, step_id, "in"))
    task.add(instance.set_state(state_name))
    task.add(build_wf_event_task(instance, step_id, "ok"))
    #ctx.internal.send_workflow_event(
    #        event_type='other',
    #        message="return: set_state_task_for_instance(node_id: {0}, state_name: {1}, step_id: {2}, instance: {3})".format(node_id, state_name, step_id, instance))
    return task
예제 #2
0
def set_state_task_for_instance(ctx, graph, node_id, instance, state_name,
                                step_id):
    #ctx.internal.send_workflow_event(
    #        event_type='other',
    #        message="call: set_state_task_for_instance(node_id: {0}, state_name: {1}, step_id: {2}, instance: {3})".format(node_id, state_name, step_id, instance))
    task = TaskSequenceWrapper(graph)
    task.add(build_wf_event_task(instance, step_id, "in"))
    task.add(instance.set_state(state_name))
    task.add(build_wf_event_task(instance, step_id, "ok"))
    #ctx.internal.send_workflow_event(
    #        event_type='other',
    #        message="return: set_state_task_for_instance(node_id: {0}, state_name: {1}, step_id: {2}, instance: {3})".format(node_id, state_name, step_id, instance))
    return task
def _delegate_workflow_event(graph, node_id, step_id, operation_fqname, custom_context, stage):
    sequence = None
    instances = custom_context.modified_instances_per_node.get(node_id, [])
    instance_count = len(instances)
    if instance_count == 1:
        sequence = build_wf_event_task(instances[0], step_id, stage, operation_fqname)
    elif instance_count > 1:
        fork = ForkjoinWrapper(graph)
        for instance in instances:
            instance_task = build_wf_event_task(instance, step_id, stage, operation_fqname)
            fork.add(instance_task)
        msg = "workflow event for step {0} on all {1} node instances".format(step_id, node_id)
        sequence = forkjoin_sequence(graph, fork, instances[0], msg)
    return sequence
def operation_task_for_instance(ctx, graph, node_id, instance, operation_fqname, step_id):
    sequence = TaskSequenceWrapper(graph)
    sequence.add(build_wf_event_task(instance, step_id, "in"))
    if operation_fqname == 'cloudify.interfaces.lifecycle.start':
        sequence.add(instance.execute_operation(operation_fqname))
        if _is_host_node_instance(instance):
            sequence.add(*host_post_start(ctx, instance))
        sequence.add(instance.execute_operation('cloudify.interfaces.monitoring.start'))
        host_instance = None
        sequence.add(instance.send_event("Start monitoring on node '{0}' instance '{1}'".format(node_id, instance.id)))
        if host_instance is not None and host_instance.id == instance.id:
            ctx.logger.info("[MAPPING] Do nothing it is the same instance: host_instance.id={} instance.id={}".format(
                host_instance.id, instance.id))
        elif 'cloudify.nodes.Compute' in instance.node.type_hierarchy:
            # This part is specific to Azure as with the Azure plugin, the relationship is from the Compute to a Volume
            for relationship in instance.relationships:
                # In the Azure definition types of the Cloudify plugin, the datadisk type doesn't derived from cloudify.nodes.Volume
                if 'cloudify.azure.nodes.storage.DataDisk' in relationship.target_node_instance.node.type_hierarchy and 'alien4cloud.mapping.device.execute' in instance.node.operations:
                    volume_instance_id = relationship.target_id
                    sequence.add(instance.send_event(
                        "Updating device attribute for instance {} and volume {} (Azure)".format(instance.id,
                                                                                                 volume_instance_id)))
                    sequence.add(instance.execute_operation("alien4cloud.mapping.device.execute",
                                                            kwargs={'volume_instance_id': volume_instance_id}))
        elif host_instance is not None and 'alien4cloud.mapping.device.execute' in host_instance.node.operations:
            sequence.add(host_instance.send_event(
                "Updating device attribute for instance {} and volume {}".format(host_instance.id, instance.id)))
            sequence.add(host_instance.execute_operation("alien4cloud.mapping.device.execute",
                                                         kwargs={'volume_instance_id': instance.id}))
    elif operation_fqname == 'cloudify.interfaces.lifecycle.configure':
        # the configure operation call itself
        sequence.add(instance.execute_operation(operation_fqname))
        persistent_event_tasks = build_persistent_event_tasks(instance)
        if persistent_event_tasks is not None:
            sequence.add(*persistent_event_tasks)
    elif operation_fqname == 'cloudify.interfaces.lifecycle.stop':
        if _is_host_node_instance(instance):
            sequence.add(*host_pre_stop(instance))
        task = instance.execute_operation(operation_fqname)
        sequence.add(task)
    elif operation_fqname == 'cloudify.interfaces.lifecycle.delete':
        task = instance.execute_operation(operation_fqname)
        sequence.add(task)
    else:
        # the default behavior : just do the job
        sequence.add(instance.execute_operation(operation_fqname))
    sequence.add(build_wf_event_task(instance, step_id, "ok"))
    return sequence
def operation_task_for_instance(ctx, graph, node_id, instance, operation_fqname, step_id, custom_context):
    sequence = TaskSequenceWrapper(graph)
    sequence.add(build_wf_event_task(instance, step_id, "in"))
    relationship_count = count_relationships(instance)
    if operation_fqname == 'cloudify.interfaces.lifecycle.start':
        sequence.add(instance.execute_operation(operation_fqname))
        if _is_host_node(instance):
            sequence.add(*host_post_start(ctx, instance))
        fork = ForkjoinWrapper(graph)
        fork.add(instance.execute_operation('cloudify.interfaces.monitoring.start'))
        if relationship_count > 0:
            for relationship in instance.relationships:
                fork.add(relationship.execute_source_operation('cloudify.interfaces.relationship_lifecycle.establish'))
                fork.add(relationship.execute_target_operation('cloudify.interfaces.relationship_lifecycle.establish'))
        sequence.add(
            instance.send_event("Start monitoring on node '{0}' instance '{1}'".format(node_id, instance.id)),
            forkjoin_sequence(graph, fork, instance, "establish")
        )
    elif operation_fqname == 'cloudify.interfaces.lifecycle.configure':
        as_target_relationships = custom_context.relationship_targets.get(instance.id, set())
        if relationship_count > 0 or len(as_target_relationships) > 0:
            preconfigure_tasks = ForkjoinWrapper(graph)
            for relationship in instance.relationships:
                preconfigure_tasks.add(relationship.execute_source_operation('cloudify.interfaces.relationship_lifecycle.preconfigure'))
            for relationship in as_target_relationships:
                preconfigure_tasks.add(relationship.execute_target_operation('cloudify.interfaces.relationship_lifecycle.preconfigure'))
            sequence.add(forkjoin_sequence(graph, preconfigure_tasks, instance, "preconf for {0}".format(instance.id)))
        sequence.add(instance.execute_operation(operation_fqname))
        if relationship_count > 0 or len(as_target_relationships) > 0:
            postconfigure_tasks = ForkjoinWrapper(graph)
            for relationship in instance.relationships:
                postconfigure_tasks.add(relationship.execute_source_operation('cloudify.interfaces.relationship_lifecycle.postconfigure'))
            for relationship in as_target_relationships:
                task = relationship.execute_target_operation('cloudify.interfaces.relationship_lifecycle.postconfigure')
                _set_send_node_event_on_error_handler(task, instance, "Error occurred while postconfiguring node as target for relationship {0} - ignoring...".format(relationship))
                postconfigure_tasks.add(task)
            msg = "postconf for {0}".format(instance.id)
            sequence.add(forkjoin_sequence(graph, postconfigure_tasks, instance, msg))

        persistent_event_task = build_persistent_event_task(instance)
        if persistent_event_task is not None:
            sequence.add(persistent_event_task)


    elif operation_fqname == 'cloudify.interfaces.lifecycle.stop':
        if _is_host_node(instance):
            sequence.add(*host_pre_stop(instance))
        task = instance.execute_operation(operation_fqname)
        _set_send_node_event_on_error_handler(task, instance, "Error occurred while stopping node - ignoring...")
        sequence.add(task)
        # now call unlink onto relations' target
        if relationship_count > 0:
            fork = ForkjoinWrapper(graph)
            for relationship in instance.relationships:
                unlink_task_source = relationship.execute_source_operation('cloudify.interfaces.relationship_lifecycle.unlink')
                _set_send_node_event_on_error_handler(unlink_task_source, instance, "Error occurred while unlinking node from target {0} - ignoring...".format(relationship.target_id))
                fork.add(unlink_task_source)
                unlink_task_target = relationship.execute_target_operation('cloudify.interfaces.relationship_lifecycle.unlink')
                _set_send_node_event_on_error_handler(unlink_task_target, instance, "Error occurred while unlinking node from target {0} - ignoring...".format(relationship.target_id))
                fork.add(unlink_task_target)
            sequence.add(forkjoin_sequence(graph, fork, instance, "unlink"))
    elif operation_fqname == 'cloudify.interfaces.lifecycle.delete':
        task = instance.execute_operation(operation_fqname)
        _set_send_node_event_on_error_handler(task, instance, "Error occurred while deleting node - ignoring...")
        sequence.add(task)
    else:
        # the default behavior : just do the job
        sequence.add(instance.execute_operation(operation_fqname))
    sequence.add(build_wf_event_task(instance, step_id, "ok"))
    return sequence
def set_state_task_for_instance(graph, node_id, instance, state_name, step_id):
    task = TaskSequenceWrapper(graph)
    task.add(build_wf_event_task(instance, step_id, "in"))
    task.add(instance.set_state(state_name))
    task.add(build_wf_event_task(instance, step_id, "ok"))
    return task
def operation_task_for_instance(ctx, graph, node_id, instance, operation_fqname, step_id, custom_context):
    sequence = TaskSequenceWrapper(graph)
    sequence.add(build_wf_event_task(instance, step_id, "in"))
    relationship_count = count_relationships(instance)
    if operation_fqname == 'cloudify.interfaces.lifecycle.start':
        sequence.add(instance.execute_operation(operation_fqname))
        if _is_host_node_instance(instance):
            sequence.add(*host_post_start(ctx, instance))
        fork = ForkjoinWrapper(graph)
        fork.add(instance.execute_operation('cloudify.interfaces.monitoring.start'))
        as_target_relationships = custom_context.relationship_targets.get(instance.id, set())
        host_instance = None
        if relationship_count > 0 or len(as_target_relationships) > 0:
            for relationship in instance.relationships:
                # add a condition in order to test if it's a 1-1 rel
                if should_call_relationship_op(ctx, relationship):
                    fork.add(relationship.execute_source_operation('cloudify.interfaces.relationship_lifecycle.establish'))
                    # if the target of the relation is not in modified instances, we should call the target.add_source
                    #if relationship.target_node_instance.id not in custom_context.modified_instance_ids:
                    fork.add(relationship.execute_target_operation('cloudify.interfaces.relationship_lifecycle.establish'))
                    if 'cloudify.nodes.Volume' in instance.node.type_hierarchy:
                        host_instance = __get_host(ctx, relationship.target_node_instance)
            for relationship in as_target_relationships:
                # add a condition in order to test if it's a 1-1 rel
                if should_call_relationship_op(ctx, relationship):
                    if relationship.node_instance.id not in custom_context.modified_instance_ids:
                        fork.add(relationship.execute_target_operation('cloudify.interfaces.relationship_lifecycle.establish'))
                    if relationship.node_instance.id not in custom_context.modified_instance_ids:
                        fork.add(relationship.execute_source_operation('cloudify.interfaces.relationship_lifecycle.establish'))
        sequence.add(
            instance.send_event("Start monitoring on node '{0}' instance '{1}'".format(node_id, instance.id)),
            forkjoin_sequence(graph, fork, instance, "establish")
        )
        if host_instance is not None and 'alien4cloud.mapping.device.execute' in host_instance.node.operations:
            sequence.add(host_instance.send_event("Updating device attribute for instance {0} and volume {0}".format(host_instance.id, instance.id)))
            sequence.add(host_instance.execute_operation("alien4cloud.mapping.device.execute", kwargs={'volume_instance_id': instance.id}))
    elif operation_fqname == 'cloudify.interfaces.lifecycle.configure':
        as_target_relationships = custom_context.relationship_targets.get(instance.id, set())
        if relationship_count > 0 or len(as_target_relationships) > 0:
            has_preconfigure_tasks = False
            preconfigure_tasks = ForkjoinWrapper(graph)
            preconfigure_tasks.add(instance.send_event("preconfiguring task for instance {0}'".format(instance.id)))
            for relationship in instance.relationships:
                # add a condition in order to test if it's a 1-1 rel
                if should_call_relationship_op(ctx, relationship):
                    if __check_and_register_call_config_arround(ctx, custom_context, relationship, 'source', 'pre'):
                        preconfigure_tasks.add(relationship.execute_source_operation('cloudify.interfaces.relationship_lifecycle.preconfigure'))
                        has_preconfigure_tasks = True
            for relationship in as_target_relationships:
                # add a condition in order to test if it's a 1-1 rel
                if should_call_relationship_op(ctx, relationship):
                    if __check_and_register_call_config_arround(ctx, custom_context, relationship, 'target', 'pre'):
                        preconfigure_tasks.add(relationship.execute_target_operation('cloudify.interfaces.relationship_lifecycle.preconfigure'))
                        has_preconfigure_tasks = True
            if has_preconfigure_tasks:
                sequence.add(forkjoin_sequence(graph, preconfigure_tasks, instance, "preconf for {0}".format(instance.id)))
        # the configure operation call itself
        sequence.add(instance.execute_operation(operation_fqname))
        if relationship_count > 0 or len(as_target_relationships) > 0:
            has_postconfigure_tasks = False
            postconfigure_tasks = ForkjoinWrapper(graph)
            postconfigure_tasks.add(instance.send_event("postconfiguring task for instance {0}'".format(instance.id)))
            for relationship in instance.relationships:
                # add a condition in order to test if it's a 1-1 rel
                if should_call_relationship_op(ctx, relationship):
                    if __check_and_register_call_config_arround(ctx, custom_context, relationship, 'source', 'post'):
                        postconfigure_tasks.add(relationship.execute_source_operation('cloudify.interfaces.relationship_lifecycle.postconfigure'))
                        has_postconfigure_tasks = True
            for relationship in as_target_relationships:
                # add a condition in order to test if it's a 1-1 rel
                if should_call_relationship_op(ctx, relationship):
                    if __check_and_register_call_config_arround(ctx, custom_context, relationship, 'target', 'post'):
                        task = relationship.execute_target_operation('cloudify.interfaces.relationship_lifecycle.postconfigure')
                        _set_send_node_event_on_error_handler(task, instance, "Error occurred while postconfiguring node as target for relationship {0} - ignoring...".format(relationship))
                        postconfigure_tasks.add(task)
                        has_postconfigure_tasks = True
            if has_postconfigure_tasks:
                sequence.add(forkjoin_sequence(graph, postconfigure_tasks, instance, "postconf for {0}".format(instance.id)))

        persistent_event_tasks = build_persistent_event_tasks(instance)
        if persistent_event_tasks is not None:
            sequence.add(*persistent_event_tasks)

    elif operation_fqname == 'cloudify.interfaces.lifecycle.stop':
        if _is_host_node_instance(instance):
            sequence.add(*host_pre_stop(instance))
        task = instance.execute_operation(operation_fqname)
        _set_send_node_event_on_error_handler(task, instance, "Error occurred while stopping node - ignoring...")
        sequence.add(task)
        as_target_relationships = custom_context.relationship_targets.get(instance.id, set())
        # now call unlink onto relations' target
        if relationship_count > 0 or len(as_target_relationships) > 0:
            fork = ForkjoinWrapper(graph)
            for relationship in instance.relationships:
                # add a condition in order to test if it's a 1-1 rel
                if should_call_relationship_op(ctx, relationship):
                    unlink_task_source = relationship.execute_source_operation('cloudify.interfaces.relationship_lifecycle.unlink')
                    _set_send_node_event_on_error_handler(unlink_task_source, instance, "Error occurred while unlinking node from target {0} - ignoring...".format(relationship.target_id))
                    fork.add(unlink_task_source)
                    # call unlink on the target of the relationship
                    unlink_task_target = relationship.execute_target_operation('cloudify.interfaces.relationship_lifecycle.unlink')
                    _set_send_node_event_on_error_handler(unlink_task_target, instance, "Error occurred while unlinking node from target {0} - ignoring...".format(relationship.target_id))
                    fork.add(unlink_task_target)
            for relationship in as_target_relationships:
                # add a condition in order to test if it's a 1-1 rel
                if should_call_relationship_op(ctx, relationship):
                    if relationship.node_instance.id not in custom_context.modified_instance_ids:
                        unlink_task_source = relationship.execute_source_operation('cloudify.interfaces.relationship_lifecycle.unlink')
                        _set_send_node_event_on_error_handler(unlink_task_source, instance, "Error occurred while unlinking node from target {0} - ignoring...".format(relationship.target_id))
                        fork.add(unlink_task_source)

            if fork.is_not_empty():
                sequence.add(forkjoin_sequence(graph, fork, instance, "unlink"))

    elif operation_fqname == 'cloudify.interfaces.lifecycle.delete':
        task = instance.execute_operation(operation_fqname)
        _set_send_node_event_on_error_handler(task, instance, "Error occurred while deleting node - ignoring...")
        sequence.add(task)
    else:
        # the default behavior : just do the job
        sequence.add(instance.execute_operation(operation_fqname))
    sequence.add(build_wf_event_task(instance, step_id, "ok"))
    return sequence
예제 #8
0
def operation_task_for_instance(ctx, graph, node_id, instance,
                                operation_fqname, step_id, custom_context):
    sequence = TaskSequenceWrapper(graph)
    sequence.add(build_wf_event_task(instance, step_id, "in"))
    relationship_count = count_relationships(instance)
    if operation_fqname == 'cloudify.interfaces.lifecycle.start':
        sequence.add(instance.execute_operation(operation_fqname))
        if _is_host_node_instance(instance):
            sequence.add(*host_post_start(ctx, instance))
        fork = ForkjoinWrapper(graph)
        fork.add(
            instance.execute_operation('cloudify.interfaces.monitoring.start'))
        as_target_relationships = custom_context.relationship_targets.get(
            instance.id, set())
        host_instance = None
        if relationship_count > 0 or len(as_target_relationships) > 0:
            for relationship in instance.relationships:
                # add a condition in order to test if it's a 1-1 rel
                if should_call_relationship_op(ctx, relationship):
                    fork.add(
                        relationship.execute_source_operation(
                            'cloudify.interfaces.relationship_lifecycle.establish'
                        ))
                    # if the target of the relation is not in modified instances, we should call the target.add_source
                    #if relationship.target_node_instance.id not in custom_context.modified_instance_ids:
                    fork.add(
                        relationship.execute_target_operation(
                            'cloudify.interfaces.relationship_lifecycle.establish'
                        ))
                    if 'cloudify.nodes.Volume' in instance.node.type_hierarchy:
                        host_instance = __get_host(
                            ctx, relationship.target_node_instance)
            for relationship in as_target_relationships:
                # add a condition in order to test if it's a 1-1 rel
                if should_call_relationship_op(ctx, relationship):
                    if relationship.node_instance.id not in custom_context.modified_instance_ids:
                        fork.add(
                            relationship.execute_target_operation(
                                'cloudify.interfaces.relationship_lifecycle.establish'
                            ))
                    if relationship.node_instance.id not in custom_context.modified_instance_ids:
                        fork.add(
                            relationship.execute_source_operation(
                                'cloudify.interfaces.relationship_lifecycle.establish'
                            ))
        sequence.add(
            instance.send_event(
                "Start monitoring on node '{0}' instance '{1}'".format(
                    node_id, instance.id)),
            forkjoin_sequence(graph, fork, instance, "establish"))
        if host_instance is not None and 'alien4cloud.mapping.device.execute' in host_instance.node.operations:
            sequence.add(
                host_instance.send_event(
                    "Updating device attribute for instance {0} and volume {0}"
                    .format(host_instance.id, instance.id)))
            sequence.add(
                host_instance.execute_operation(
                    "alien4cloud.mapping.device.execute",
                    kwargs={'volume_instance_id': instance.id}))
    elif operation_fqname == 'cloudify.interfaces.lifecycle.configure':
        as_target_relationships = custom_context.relationship_targets.get(
            instance.id, set())
        if relationship_count > 0 or len(as_target_relationships) > 0:
            has_preconfigure_tasks = False
            preconfigure_tasks = ForkjoinWrapper(graph)
            preconfigure_tasks.add(
                instance.send_event(
                    "preconfiguring task for instance {0}'".format(
                        instance.id)))
            for relationship in instance.relationships:
                # add a condition in order to test if it's a 1-1 rel
                if should_call_relationship_op(ctx, relationship):
                    if __check_and_register_call_config_arround(
                            ctx, custom_context, relationship, 'source',
                            'pre'):
                        preconfigure_tasks.add(
                            relationship.execute_source_operation(
                                'cloudify.interfaces.relationship_lifecycle.preconfigure'
                            ))
                        has_preconfigure_tasks = True
            for relationship in as_target_relationships:
                # add a condition in order to test if it's a 1-1 rel
                if should_call_relationship_op(ctx, relationship):
                    if __check_and_register_call_config_arround(
                            ctx, custom_context, relationship, 'target',
                            'pre'):
                        preconfigure_tasks.add(
                            relationship.execute_target_operation(
                                'cloudify.interfaces.relationship_lifecycle.preconfigure'
                            ))
                        has_preconfigure_tasks = True
            if has_preconfigure_tasks:
                sequence.add(
                    forkjoin_sequence(graph, preconfigure_tasks, instance,
                                      "preconf for {0}".format(instance.id)))
        # the configure operation call itself
        sequence.add(instance.execute_operation(operation_fqname))
        if relationship_count > 0 or len(as_target_relationships) > 0:
            has_postconfigure_tasks = False
            postconfigure_tasks = ForkjoinWrapper(graph)
            postconfigure_tasks.add(
                instance.send_event(
                    "postconfiguring task for instance {0}'".format(
                        instance.id)))
            for relationship in instance.relationships:
                # add a condition in order to test if it's a 1-1 rel
                if should_call_relationship_op(ctx, relationship):
                    if __check_and_register_call_config_arround(
                            ctx, custom_context, relationship, 'source',
                            'post'):
                        postconfigure_tasks.add(
                            relationship.execute_source_operation(
                                'cloudify.interfaces.relationship_lifecycle.postconfigure'
                            ))
                        has_postconfigure_tasks = True
            for relationship in as_target_relationships:
                # add a condition in order to test if it's a 1-1 rel
                if should_call_relationship_op(ctx, relationship):
                    if __check_and_register_call_config_arround(
                            ctx, custom_context, relationship, 'target',
                            'post'):
                        task = relationship.execute_target_operation(
                            'cloudify.interfaces.relationship_lifecycle.postconfigure'
                        )
                        _set_send_node_event_on_error_handler(
                            task, instance,
                            "Error occurred while postconfiguring node as target for relationship {0} - ignoring..."
                            .format(relationship))
                        postconfigure_tasks.add(task)
                        has_postconfigure_tasks = True
            if has_postconfigure_tasks:
                sequence.add(
                    forkjoin_sequence(graph, postconfigure_tasks, instance,
                                      "postconf for {0}".format(instance.id)))

        persistent_event_tasks = build_persistent_event_tasks(instance)
        if persistent_event_tasks is not None:
            sequence.add(*persistent_event_tasks)

    elif operation_fqname == 'cloudify.interfaces.lifecycle.stop':
        if _is_host_node_instance(instance):
            sequence.add(*host_pre_stop(instance))
        task = instance.execute_operation(operation_fqname)
        _set_send_node_event_on_error_handler(
            task, instance, "Error occurred while stopping node - ignoring...")
        sequence.add(task)
        as_target_relationships = custom_context.relationship_targets.get(
            instance.id, set())
        # now call unlink onto relations' target
        if relationship_count > 0 or len(as_target_relationships) > 0:
            fork = ForkjoinWrapper(graph)
            for relationship in instance.relationships:
                # add a condition in order to test if it's a 1-1 rel
                if should_call_relationship_op(ctx, relationship):
                    unlink_task_source = relationship.execute_source_operation(
                        'cloudify.interfaces.relationship_lifecycle.unlink')
                    _set_send_node_event_on_error_handler(
                        unlink_task_source, instance,
                        "Error occurred while unlinking node from target {0} - ignoring..."
                        .format(relationship.target_id))
                    fork.add(unlink_task_source)
                    if relationship.target_node_instance.id not in custom_context.modified_instance_ids:
                        unlink_task_target = relationship.execute_target_operation(
                            'cloudify.interfaces.relationship_lifecycle.unlink'
                        )
                        _set_send_node_event_on_error_handler(
                            unlink_task_target, instance,
                            "Error occurred while unlinking node from target {0} - ignoring..."
                            .format(relationship.target_id))
                        fork.add(unlink_task_target)
            for relationship in as_target_relationships:
                # add a condition in order to test if it's a 1-1 rel
                if should_call_relationship_op(ctx, relationship):
                    unlink_task_target = relationship.execute_target_operation(
                        'cloudify.interfaces.relationship_lifecycle.unlink')
                    _set_send_node_event_on_error_handler(
                        unlink_task_target, instance,
                        "Error occurred while unlinking node from target {0} - ignoring..."
                        .format(relationship.target_id))
                    fork.add(unlink_task_target)
                    if relationship.node_instance.id not in custom_context.modified_instance_ids:
                        unlink_task_source = relationship.execute_source_operation(
                            'cloudify.interfaces.relationship_lifecycle.unlink'
                        )
                        _set_send_node_event_on_error_handler(
                            unlink_task_source, instance,
                            "Error occurred while unlinking node from target {0} - ignoring..."
                            .format(relationship.target_id))
                        fork.add(unlink_task_source)

            sequence.add(forkjoin_sequence(graph, fork, instance, "unlink"))

    elif operation_fqname == 'cloudify.interfaces.lifecycle.delete':
        task = instance.execute_operation(operation_fqname)
        _set_send_node_event_on_error_handler(
            task, instance, "Error occurred while deleting node - ignoring...")
        sequence.add(task)
    else:
        # the default behavior : just do the job
        sequence.add(instance.execute_operation(operation_fqname))
    sequence.add(build_wf_event_task(instance, step_id, "ok"))
    return sequence
def operation_task_for_native_instance(ctx, graph, node_id, instance, operation_fqname, step_id, custom_context):
    sequence = TaskSequenceWrapper(graph)
    sequence.add(build_wf_event_task(instance, step_id, "in", operation_fqname))
    relationship_count = count_relationships(instance)
    if operation_fqname == 'cloudify.interfaces.lifecycle.start':
        sequence.add(instance.execute_operation(operation_fqname))
        if _is_host_node_instance(instance):
            sequence.add(*host_post_start(ctx, instance))
        sequence.add(instance.execute_operation('cloudify.interfaces.monitoring.start'))
        as_target_relationships = custom_context.relationship_targets.get(instance.id, set())
        host_instance = None
        if relationship_count > 0 or len(as_target_relationships) > 0:
            for relationship in instance.relationships:
                # add a condition in order to test if it's a 1-1 rel
                if should_call_relationship_op(ctx, relationship):
                    sequence.add(
                        relationship.execute_source_operation('cloudify.interfaces.relationship_lifecycle.establish'))
                    # if the target of the relation is not in modified instances, we should call the target.add_source
                    # if relationship.target_node_instance.id not in custom_context.modified_instance_ids:
                    sequence.add(
                        relationship.execute_target_operation('cloudify.interfaces.relationship_lifecycle.establish'))
                    if 'cloudify.nodes.Volume' in instance.node.type_hierarchy:
                        ctx.logger.info(
                            "[MAPPING] instance={} hierarchy={}".format(instance.id, instance.node.type_hierarchy))
                        host_instance = __get_host(ctx, relationship.target_node_instance)
            for relationship in as_target_relationships:
                # add a condition in order to test if it's a 1-1 rel
                if should_call_relationship_op(ctx, relationship):
                    if relationship.node_instance.id not in custom_context.modified_instance_ids:
                        sequence.add(relationship.execute_target_operation(
                            'cloudify.interfaces.relationship_lifecycle.establish'))
                    if relationship.node_instance.id not in custom_context.modified_instance_ids:
                        sequence.add(relationship.execute_source_operation(
                            'cloudify.interfaces.relationship_lifecycle.establish'))
        sequence.add(instance.send_event("Start monitoring on node '{0}' instance '{1}'".format(node_id, instance.id)))
        if host_instance is not None and host_instance.id == instance.id:
            ctx.logger.info("[MAPPING] Do nothing it is the same instance: host_instance.id={} instance.id={}".format(
                host_instance.id, instance.id))
        elif 'cloudify.nodes.Compute' in instance.node.type_hierarchy:
            # This part is specific to Azure as with the Azure plugin, the relationship is from the Compute to a Volume
            for relationship in instance.relationships:
                # In the Azure definition types of the Cloudify plugin, the datadisk type doesn't derived from cloudify.nodes.Volume
                if 'cloudify.azure.nodes.storage.DataDisk' in relationship.target_node_instance.node.type_hierarchy and 'alien4cloud.mapping.device.execute' in instance.node.operations:
                    volume_instance_id = relationship.target_id
                    sequence.add(instance.send_event(
                        "Updating device attribute for instance {} and volume {} (Azure)".format(instance.id,
                                                                                                 volume_instance_id)))
                    sequence.add(instance.execute_operation("alien4cloud.mapping.device.execute",
                                                            kwargs={'volume_instance_id': volume_instance_id}))
        elif host_instance is not None and 'alien4cloud.mapping.device.execute' in host_instance.node.operations:
            sequence.add(host_instance.send_event(
                "Updating device attribute for instance {} and volume {}".format(host_instance.id, instance.id)))
            sequence.add(host_instance.execute_operation("alien4cloud.mapping.device.execute",
                                                         kwargs={'volume_instance_id': instance.id}))
    elif operation_fqname == 'cloudify.interfaces.lifecycle.configure':
        as_target_relationships = custom_context.relationship_targets.get(instance.id, set())
        if relationship_count > 0 or len(as_target_relationships) > 0:
            sequence.add(instance.send_event("preconfiguring task for instance {0}'".format(instance.id)))
            for relationship in instance.relationships:
                # add a condition in order to test if it's a 1-1 rel
                if should_call_relationship_op(ctx, relationship):
                    if __check_and_register_call_config_around(ctx, custom_context, relationship, 'source', 'pre'):
                        sequence.add(relationship.execute_source_operation(
                            'cloudify.interfaces.relationship_lifecycle.preconfigure'))
            for relationship in as_target_relationships:
                # add a condition in order to test if it's a 1-1 rel
                if should_call_relationship_op(ctx, relationship):
                    if __check_and_register_call_config_around(ctx, custom_context, relationship, 'target', 'pre'):
                        sequence.add(relationship.execute_target_operation(
                            'cloudify.interfaces.relationship_lifecycle.preconfigure'))
        # the configure operation call itself
        sequence.add(instance.execute_operation(operation_fqname))
        if relationship_count > 0 or len(as_target_relationships) > 0:
            sequence.add(instance.send_event("postconfiguring task for instance {0}'".format(instance.id)))
            for relationship in instance.relationships:
                # add a condition in order to test if it's a 1-1 rel
                if should_call_relationship_op(ctx, relationship):
                    if __check_and_register_call_config_around(ctx, custom_context, relationship, 'source', 'post'):
                        sequence.add(relationship.execute_source_operation(
                            'cloudify.interfaces.relationship_lifecycle.postconfigure'))
                        has_postconfigure_tasks = True
            for relationship in as_target_relationships:
                # add a condition in order to test if it's a 1-1 rel
                if should_call_relationship_op(ctx, relationship):
                    if __check_and_register_call_config_around(ctx, custom_context, relationship, 'target', 'post'):
                        task = relationship.execute_target_operation(
                            'cloudify.interfaces.relationship_lifecycle.postconfigure')
                        _set_send_node_event_on_error_handler(task, instance,
                                                              "Error occurred while postconfiguring node as target for relationship {0} - ignoring...".format(
                                                                  relationship))
                        sequence.add(task)

        persistent_event_tasks = build_persistent_event_tasks(instance)
        if persistent_event_tasks is not None:
            sequence.add(*persistent_event_tasks)

    elif operation_fqname == 'cloudify.interfaces.lifecycle.stop':
        if _is_host_node_instance(instance):
            sequence.add(*host_pre_stop(instance))
        task = instance.execute_operation(operation_fqname)

        if custom_context.is_native_node(instance):
            def send_node_event_error_handler(tsk):
                instance.send_event('ignore stop failure')
                return workflow_tasks.HandlerResult.ignore()

            task.on_failure = send_node_event_error_handler

        sequence.add(task)
        as_target_relationships = custom_context.relationship_targets.get(instance.id, set())
        # now call unlink onto relations' target
        if relationship_count > 0 or len(as_target_relationships) > 0:
            for relationship in instance.relationships:
                # add a condition in order to test if it's a 1-1 rel
                if should_call_relationship_op(ctx, relationship):
                    unlink_task_source = relationship.execute_source_operation(
                        'cloudify.interfaces.relationship_lifecycle.unlink')
                    sequence.add(unlink_task_source)
                    # call unlink on the target of the relationship
                    unlink_task_target = relationship.execute_target_operation(
                        'cloudify.interfaces.relationship_lifecycle.unlink')
                    sequence.add(unlink_task_target)
            for relationship in as_target_relationships:
                # add a condition in order to test if it's a 1-1 rel
                if should_call_relationship_op(ctx, relationship):
                    if relationship.node_instance.id not in custom_context.modified_instance_ids:
                        unlink_task_source = relationship.execute_source_operation(
                            'cloudify.interfaces.relationship_lifecycle.unlink')
                        sequence.add(unlink_task_source)
                        unlink_task_target = relationship.execute_target_operation(
                            'cloudify.interfaces.relationship_lifecycle.unlink')
                        sequence.add(unlink_task_target)


    elif operation_fqname == 'cloudify.interfaces.lifecycle.delete':
        task = instance.execute_operation(operation_fqname)

        if custom_context.is_native_node(instance):
            def send_node_event_error_handler(tsk):
                instance.send_event('ignore delete failure')
                return workflow_tasks.HandlerResult.ignore()

            task.on_failure = send_node_event_error_handler

        sequence.add(task)
    else:
        # the default behavior : just do the job
        sequence.add(instance.execute_operation(operation_fqname))
    sequence.add(build_wf_event_task(instance, step_id, "ok", operation_fqname))
    return sequence