<commit_before>from distutils.util import strtobool  # pylint: disable=import-error,no-name-in-module
from pprint import pformat
from fabric.api import task, local, run, sudo, put, get, abort, settings
import fabric.state
from fabric.contrib import files
import aws, utils
from decorators import requires_project, requires_aws_stack, requires_steady_stack, echo_output, setdefault, debugtask, timeit
from buildercore import core, cfngen, utils as core_utils, bootstrap, project, checks, lifecycle as core_lifecycle, context_handler
from buildercore.concurrency import concurrency_for
from buildercore.core import stack_conn, stack_pem, stack_all_ec2_nodes
from buildercore.decorators import PredicateException
from buildercore.config import DEPLOY_USER, BOOTSTRAP_USER, FabricException

import logging
LOG = logging.getLogger(__name__)

# these aliases are deprecated
@task(alias='aws_delete_stack')
@requires_steady_stack
def destroy(stackname):
    "tell aws to delete a stack."
    print 'this is a BIG DEAL. you cannot recover from this.'
    print 'type the name of the stack to continue or anything else to quit'
    uin = raw_input('> ')
    if not uin or not uin.strip().lower() == stackname.lower():
        import difflib
        print 'you needed to type "%s" to continue.' % stackname
        print 'got:'
        print '\n'.join(difflib.ndiff([stackname], [uin]))
        exit(1)
    return bootstrap.delete_stack(stackname)
@task
def ensure_destroyed(stackname):
    try:
        return bootstrap.delete_stack(stackname)
    except PredicateException as e:
        if "I couldn't find a cloudformation stack" in str(e):
            print "Not even the CloudFormation template exists anymore, exiting idempotently"
            return
        raise

# these aliases are deprecated
@task(alias='aws_update_stack')
@requires_aws_stack
@timeit
def update(stackname, *service_list):
    """Updates the environment within the stack's ec2 instance.
    does *not* call Cloudformation's `update` command on the stack"""
    instances = _check_want_to_be_running(stackname)
    if not instances:
        return
    return bootstrap.update_stack(stackname, service_list, concurrency='serial')

@task
@timeit
def update_template(stackname):
    """Limited update of the Cloudformation template.

    Resources can be added, but most of the existing ones are immutable.

    Some resources are updatable in place.

    Moreover, we never add anything related to EC2 instances as they are
    not supported anyway (they will come up as part of the template
    but without any software being on it)

    Moreover, EC2 instances must be running while this is executed or their
    resources like PublicIP will be inaccessible"""

    (pname, _) = core.parse_stackname(stackname)
    more_context = cfngen.choose_config(stackname)

    context, delta = cfngen.regenerate_stack(pname, **more_context)

    if context['ec2']:
        core_lifecycle.start(stackname)
    LOG.info("%s", pformat(delta))
    if not delta['Resources'] and not delta['Outputs']:
        LOG.info("Nothing to update")
        return
    utils.confirm('Confirming changes to the stack template?')

    context_handler.write_context(stackname, context)
    new_template = cfngen.merge_delta(stackname, delta)
    bootstrap.update_template(stackname, new_template)

    update(stackname)


@task
def update_master():
    return bootstrap.update_stack(core.find_master(aws.find_region()))

@requires_project
def generate_stack_from_input(pname, instance_id=None):
    """creates a new CloudFormation file for the given project."""
    if not instance_id:
        default_instance_id = core_utils.ymd()
        instance_id = utils.uin("instance id", default_instance_id)
    stackname = core.mk_stackname(pname, instance_id)
    more_context = {'stackname': stackname}

    # prompt user for alternate configurations
    pdata = project.project_data(pname)
    if 'aws-alt' in pdata:<commit_msg>Updated context even without the template<commit_after>from distutils.util import strtobool  # pylint: disable=import-error,no-name-in-module
from pprint import pformat
from fabric.api import task, local, run, sudo, put, get, abort, settings
import fabric.state
from fabric.contrib import files
import aws, utils
from decorators import requires_project, requires_aws_stack, requires_steady_stack, echo_output, setdefault, debugtask, timeit
from buildercore import core, cfngen, utils as core_utils, bootstrap, project, checks, lifecycle as core_lifecycle, context_handler
from buildercore.concurrency import concurrency_for
from buildercore.core import stack_conn, stack_pem, stack_all_ec2_nodes
from buildercore.decorators import PredicateException
from buildercore.config import DEPLOY_USER, BOOTSTRAP_USER, FabricException

import logging
LOG = logging.getLogger(__name__)

# these aliases are deprecated
@task(alias='aws_delete_stack')
@requires_steady_stack
def destroy(stackname):
    "tell aws to delete a stack."
    print 'this is a BIG DEAL. you cannot recover from this.'
    print 'type the name of the stack to continue or anything else to quit'
    uin = raw_input('> ')
    if not uin or not uin.strip().lower() == stackname.lower():
        import difflib
        print 'you needed to type "%s" to continue.' % stackname
        print 'got:'
        print '\n'.join(difflib.ndiff([stackname], [uin]))
        exit(1)
    return bootstrap.delete_stack(stackname)
@task
def ensure_destroyed(stackname):
    try:
        return bootstrap.delete_stack(stackname)
    except PredicateException as e:
        if "I couldn't find a cloudformation stack" in str(e):
            print "Not even the CloudFormation template exists anymore, exiting idempotently"
            return
        raise

# these aliases are deprecated
@task(alias='aws_update_stack')
@requires_aws_stack
@timeit
def update(stackname, *service_list):
    """Updates the environment within the stack's ec2 instance.
    does *not* call Cloudformation's `update` command on the stack"""
    instances = _check_want_to_be_running(stackname)
    if not instances:
        return
    return bootstrap.update_stack(stackname, service_list, concurrency='serial')

@task
@timeit
def update_template(stackname):
    """Limited update of the Cloudformation template.

    Resources can be added, but most of the existing ones are immutable.

    Some resources are updatable in place.

    Moreover, we never add anything related to EC2 instances as they are
    not supported anyway (they will come up as part of the template
    but without any software being on it)

    Moreover, EC2 instances must be running while this is executed or their
    resources like PublicIP will be inaccessible"""

    (pname, _) = core.parse_stackname(stackname)
    more_context = cfngen.choose_config(stackname)

    context, delta = cfngen.regenerate_stack(pname, **more_context)

    if context['ec2']:
        core_lifecycle.start(stackname)
    LOG.info("%s", pformat(delta))
    utils.confirm('Confirming changes to the stack template? This will rewrite the context and the CloudFormation template')

    context_handler.write_context(stackname, context)

    if delta['Resources'] or delta['Outputs']:
        new_template = cfngen.merge_delta(stackname, delta)
        bootstrap.update_template(stackname, new_template)
    else:
        # attempting to apply an empty change set would result in an error
        LOG.info("Nothing to update on CloudFormation")

    update(stackname)


@task
def update_master():
    return bootstrap.update_stack(core.find_master(aws.find_region()))

@requires_project
def generate_stack_from_input(pname, instance_id=None):
    """creates a new CloudFormation file for the given project."""
    if not instance_id:
        default_instance_id = core_utils.ymd()
        instance_id = utils.uin("instance id", default_instance_id)
    stackname = core.mk_stackname(pname, instance_id)
    more_context = {'stackname': stackname}

    # prompt user for alternate configurations
    pdata = project.project_data(pname)
    if 'aws-alt' in pdata:
{'fraction_non_alphanumeric': 0.07922013820335637, 'fraction_numerical': 0.0014807502467917078, 'mean_word_length': 4.232408005164622, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, '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': '282718', 'n_tokens_mistral': 2343, 'n_tokens_neox': 2274, 'n_words': 771}