def terminate_virtualized_cluster(cls, keyname, clean, is_verbose):
    """Stops all API services running on all nodes 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.
      clean: A bool representing whether clean should be ran on the nodes.
    """
    AppScaleLogger.log("Stopping appscale deployment with keyname {0}"
                       .format(keyname))
    time.sleep(2)

    shadow_host = LocalState.get_host_with_role(keyname, 'shadow')
    try:
      secret = LocalState.get_secret_key(keyname)
    except IOError:
      # We couldn't find the secret key: AppScale is most likely not
      # running.
      raise AppScaleException("Couldn't find AppScale secret key.")

    acc = AppControllerClient(shadow_host, secret)
    try:
      machines = len(acc.get_all_public_ips()) - 1
      acc.run_terminate(clean)
      terminated_successfully = True
      log_dump = u""
      while not acc.is_appscale_terminated():
        # For terminate receive_server_message will return a JSON string that
        # is a list of dicts with keys: ip, status, output
        try:
          output_list = yaml.safe_load(acc.receive_server_message())
        except Exception as e:
          log_dump += e.message
          continue
        for node in output_list:
          if node.get("status"):
            machines -= 1
            AppScaleLogger.success("Node at {node_ip}: {status}".format(
              node_ip=node.get("ip"), status="Stopping AppScale finished"))
          else:
            AppScaleLogger.warn("Node at {node_ip}: {status}".format(
              node_ip=node.get("ip"), status="Stopping AppScale failed"))
            terminated_successfully = False
            log_dump += u"Node at {node_ip}: {status}\nNode Output:"\
                        u"{output}".format(node_ip=node.get("ip"),
                                           status="Stopping AppScale failed",
                                           output=node.get("output"))
          AppScaleLogger.verbose(u"Output of node at {node_ip}:\n"
                                 u"{output}".format(node_ip=node.get("ip"),
                                                    output=node.get("output")),
                                 is_verbose)
      if not terminated_successfully or machines > 0:
        LocalState.generate_crash_log(AppControllerException, log_dump)
        raise AppScaleException("{0} node(s) failed stopping AppScale, "
                                "head node is still running AppScale services."
                                .format(machines))
      cls.stop_remote_appcontroller(shadow_host, keyname, is_verbose, clean)
    except socket.error as socket_error:
      AppScaleLogger.warn(u'Unable to talk to AppController: {}'.
                          format(socket_error.message))
      raise
    except Exception as exception:
      AppScaleLogger.verbose(u'Saw Exception while stopping AppScale {0}'.
                             format(str(exception)), is_verbose)
      raise