Пример #1
0
  def terminate_cloud_infrastructure(cls, keyname, is_verbose):
    """Powers off all machines in the currently running AppScale deployment.

    Args:
      keyname: The name of the SSH keypair used for this AppScale deployment.
      is_verbose: A bool that indicates if we should print the commands executed
        to stdout.
    """
    AppScaleLogger.log("About to terminate deployment and instances with "
                       "keyname {0}. Press Ctrl-C to stop.".format(keyname))
    # This sleep is here to allow a moment for user to Ctrl-C
    time.sleep(2)

    # get all the instance IDs for machines in our deployment
    agent = InfrastructureAgentFactory.create_agent(
      LocalState.get_infrastructure(keyname))
    params = agent.get_cloud_params(keyname)
    params['IS_VERBOSE'] = is_verbose
    params['autoscale_agent'] = False

    # We want to terminate also the pending instances.
    pending = True
    _, _, instance_ids = agent.describe_instances(params, pending=pending)

    # If using persistent disks, unmount them and detach them before we blow
    # away the instances.
    nodes = LocalState.get_local_nodes_info(keyname)
    for node in nodes:
      if node.get('disk'):
        AppScaleLogger.log("Unmounting persistent disk at {0}".
                           format(node['public_ip']))
        cls.unmount_persistent_disk(node['public_ip'], keyname, is_verbose)
        agent.detach_disk(params, node['disk'], node['instance_id'])

    # terminate all the machines
    AppScaleLogger.log("Terminating instances spawned with keyname {0}"
                       .format(keyname))
    params[agent.PARAM_INSTANCE_IDS] = instance_ids
    agent.terminate_instances(params)

    # Delete the network configuration created for the cloud.
    agent.cleanup_state(params)

    # Cleanup the keyname files created on the local filesystem.
    # For GCE and Azure, the keypairs are created on the filesystem,
    # rather than the cloud. So we have to clean up afterwards.
    LocalState.cleanup_keyname(keyname)
Пример #2
0
  def start_all_nodes(cls, options, node_layout):
    """ Starts all nodes in the designated public cloud.

    Args:
      options: A Namespace that includes parameters passed in by the user that
        define non-placement-strategy-related deployment options (e.g., keypair
        names, security group names).
      node_layout: The node layout of the system including roles.
    Returns:
      The node layout (dummy values in non-cloud deployments)
      corresponding to the nodes that were started.
    """
    agent = InfrastructureAgentFactory.create_agent(options.infrastructure)
    params = agent.get_params_from_args(options)

    # If we have running instances under the current keyname, we try to
    # re-attach to them. If we have issue finding the locations file or the
    # IP of the head node, we throw an exception.
    login_ip = None
    public_ips, private_ips, instance_ids = agent.describe_instances(params)
    if public_ips:
      try:
        login_ip = LocalState.get_login_host(options.keyname)
      except (IOError, BadConfigurationException):
        raise AppScaleException(
          "Couldn't get login ip for running deployment with keyname"
          " {}.".format(options.keyname))
      if login_ip not in public_ips:
        raise AppScaleException(
          "Couldn't recognize running instances for deployment with"
          " keyname {}.".format(options.keyname))

    if login_ip in public_ips:
      AppScaleLogger.log("Reusing already running instances.")
      # Get the node_info from the locations JSON.
      node_info = LocalState.get_local_nodes_info(keyname=options.keyname)

      previous_node_list = node_layout.from_locations_json_list(node_info)
      # If this is None, the AppScalefile has been changed or the nodes could
      # not be matched up by roles/jobs.
      if previous_node_list is None:
        raise BadConfigurationException("AppScale does not currently support "
                                        "changes to AppScalefile or locations "
                                        "JSON between a down and an up. If "
                                        "you would like to "
                                        "change the node layout use "
                                        "down --terminate before an up.")
      node_layout.nodes = previous_node_list
      for node_index, node in enumerate(node_layout.nodes):
        try:
          index = instance_ids.index(node.instance_id)
        except ValueError:
          raise BadConfigurationException("Previous instance_id {} does not "
                                          "currently exist."
                                          .format(node.instance_id))
        node_layout.nodes[node_index].public_ip = public_ips[index]
        node_layout.nodes[node_index].private_ip = private_ips[index]
        node_layout.nodes[node_index].instance_id = instance_ids[index]
      return node_layout

    agent.configure_instance_security(params)

    load_balancer_roles = {}
    instance_type_roles = {}

    for node in node_layout.get_nodes('load_balancer', True):
      load_balancer_roles.setdefault(node.instance_type, []).append(node)

    for node in node_layout.get_nodes('load_balancer', False):
      instance_type = instance_type_roles
      instance_type.setdefault(node.instance_type, []).append(node)

    spawned_instance_ids = []

    for instance_type, load_balancer_nodes in load_balancer_roles.items():
      # Copy parameters so we can modify the instance type.
      instance_type_params = params.copy()
      instance_type_params['instance_type'] = instance_type

      try:
        instance_ids, public_ips, private_ips = cls.spawn_nodes_in_cloud(
          agent, instance_type_params, count=len(load_balancer_nodes),
          load_balancer=True)
      except (AgentRuntimeException, BotoServerError):
        AppScaleLogger.warn("AppScale was unable to start the requested number "
                            "of instances, attempting to terminate those that "
                            "were started.")
        if len(spawned_instance_ids) > 0:
          AppScaleLogger.warn("Attempting to terminate those that were started.")
          cls.terminate_spawned_instances(spawned_instance_ids, agent, params)

        # Cleanup the keyname since it failed.
        LocalState.cleanup_keyname(options.keyname)

        # Re-raise the original exception.
        raise

      # Keep track of instances we have started.
      spawned_instance_ids.extend(instance_ids)

      for node_index, node in enumerate(load_balancer_nodes):
        index = node_layout.nodes.index(node)
        node_layout.nodes[index].public_ip = public_ips[node_index]
        node_layout.nodes[index].private_ip = private_ips[node_index]
        node_layout.nodes[index].instance_id = instance_ids[node_index]

    if options.static_ip:
      node = node_layout.head_node()
      agent.associate_static_ip(params, node.instance_id,
                                options.static_ip)
      node.public_ip = options.static_ip
      AppScaleLogger.log("Static IP associated with head node.")

    AppScaleLogger.log("\nPlease wait for AppScale to prepare your machines "
                       "for use. This can take few minutes.")

    for instance_type, nodes in instance_type_roles.items():
      # Copy parameters so we can modify the instance type.
      instance_type_params = params.copy()
      instance_type_params['instance_type'] = instance_type

      try:
        _instance_ids, _public_ips, _private_ips = cls.spawn_nodes_in_cloud(
          agent, instance_type_params, count=len(nodes))
      except (AgentRuntimeException, BotoServerError):
        AppScaleLogger.warn("AppScale was unable to start the requested number "
                            "of instances, attempting to terminate those that "
                            "were started.")
        if len(spawned_instance_ids) > 0:
          AppScaleLogger.warn("Attempting to terminate those that were started.")
          cls.terminate_spawned_instances(spawned_instance_ids, agent, params)

        # Cleanup the keyname since it failed.
        LocalState.cleanup_keyname(options.keyname)

        # Re-raise the original exception.
        raise

      # Keep track of instances we have started.
      spawned_instance_ids.extend(_instance_ids)

      for node_index, node in enumerate(nodes):
        index = node_layout.nodes.index(node)
        node_layout.nodes[index].public_ip = _public_ips[node_index]
        node_layout.nodes[index].private_ip = _private_ips[node_index]
        node_layout.nodes[index].instance_id = _instance_ids[node_index]

    return node_layout