Пример #1
0
  def add_access_config(self, parameters, instance_id, static_ip):
    """ Instructs Google Compute Engine to use the given IP address as the
    public IP for the named instance.

    This assumes that there is no existing public IP address for the named
    instance. If this is not the case, callers should use delete_access_config
    first to remove it.

    Args:
      parameters: A dict with keys for each parameter needed to connect to
        Google Compute Engine, and an additional key mapping to a list of
        instance names that should be deleted.
      instance_id: A str naming the running instance that the new public IP
        address should be added to.
      static_ip: A str naming the already allocated static IP address that
        will be used for the named instance.
    """
    gce_service, credentials = self.open_connection(parameters)
    http = httplib2.Http()
    auth_http = credentials.authorize(http)
    request = gce_service.instances().addAccessConfig(
      project=parameters[self.PARAM_PROJECT],
      instance=instance_id,
      networkInterface="nic0",
      zone=parameters[self.PARAM_ZONE],
      body={
        "kind": "compute#accessConfig",
        "type" : "ONE_TO_ONE_NAT",
        "name" : "External NAT",
        "natIP" : static_ip
      }
    )
    response = request.execute(http=auth_http)
    AppScaleLogger.verbose(str(response), parameters[self.PARAM_VERBOSE])
Пример #2
0
 def create_virtual_network(self, network_client, parameters, network_name,
                            subnet_name):
   """ Creates the network resources, such as Virtual network and Subnet.
   Args:
     network_client: A NetworkManagementClient instance.
     parameters:  A dict, containing all the parameters necessary to
       authenticate this user with Azure.
     network_name: The name to use for the Virtual Network resource.
     subnet_name: The name to use for the Subnet resource.
   Returns:
     A Subnet instance from the Virtual Network created.
   """
   group_name = parameters[self.PARAM_RESOURCE_GROUP]
   region = parameters[self.PARAM_ZONE]
   verbose = parameters[self.PARAM_VERBOSE]
   AppScaleLogger.verbose("Creating/Updating the Virtual Network '{}'".
                          format(network_name), verbose)
   address_space = AddressSpace(address_prefixes=['10.1.0.0/16'])
   subnet1 = Subnet(name=subnet_name, address_prefix='10.1.0.0/24')
   result = network_client.virtual_networks.create_or_update(group_name, network_name,
     VirtualNetwork(location=region, address_space=address_space,
                    subnets=[subnet1]))
   self.sleep_until_update_operation_done(result, network_name, verbose)
   subnet = network_client.subnets.get(group_name, network_name, subnet_name)
   return subnet
Пример #3
0
  def update_dispatch(cls, source_location, keyname, project_id):
    """ Updates an application's dispatch routing rules from the configuration
      file.

    Args:
      options: A Namespace that has fields for each parameter that can be
        passed in via the command-line interface.
    """
    if cls.TAR_GZ_REGEX.search(source_location):
      fetch_function = utils.config_from_tar_gz
      version = Version.from_tar_gz(source_location)
    elif cls.ZIP_REGEX.search(source_location):
      fetch_function = utils.config_from_zip
      version = Version.from_zip(source_location)
    elif os.path.isdir(source_location):
      fetch_function = utils.config_from_dir
      version = Version.from_directory(source_location)
    elif source_location.endswith('.yaml'):
      fetch_function = utils.config_from_dir
      version = Version.from_yaml_file(source_location)
      source_location = os.path.dirname(source_location)
    else:
      raise BadConfigurationException(
        '{} must be a directory, tar.gz, or zip'.format(source_location))

    if project_id:
      version.project_id = project_id

    dispatch_rules = utils.dispatch_from_yaml(source_location, fetch_function)
    if dispatch_rules is None:
        return
    AppScaleLogger.log('Updating dispatch for {}'.format(version.project_id))

    load_balancer_ip = LocalState.get_host_with_role(keyname, 'load_balancer')
    secret_key = LocalState.get_secret_key(keyname)
    admin_client = AdminClient(load_balancer_ip, secret_key)
    operation_id = admin_client.update_dispatch(version.project_id, dispatch_rules)

    # Check on the operation.
    AppScaleLogger.log("Please wait for your dispatch to be updated.")

    deadline = time.time() + cls.MAX_OPERATION_TIME
    while True:
      if time.time() > deadline:
        raise AppScaleException('The operation took too long.')
      operation = admin_client.get_operation(version.project_id, operation_id)
      if not operation['done']:
        time.sleep(1)
        continue

      if 'error' in operation:
        raise AppScaleException(operation['error']['message'])
      dispatch_rules = operation['response']['dispatchRules']
      break

    AppScaleLogger.verbose(
        "The following dispatchRules have been applied to your application's "
        "configuration : {}".format(dispatch_rules))
    AppScaleLogger.success('Dispatch has been updated for {}'.format(
        version.project_id))
Пример #4
0
  def create_network(self, parameters):
    """ Creates a new network in Google Compute Engine with the specified name.

    Args:
      parameters: A dict with keys for each parameter needed to connect to
        Google Compute Engine, and an additional key indicating the name of the
        network that we should create in GCE.
    Returns:
      The URL corresponding to the name of the network that was created, for use
      with binding this network to one or more firewalls.
    """
    gce_service, credentials = self.open_connection(parameters)
    http = httplib2.Http()
    auth_http = credentials.authorize(http)
    request = gce_service.networks().insert(
      project=parameters[self.PARAM_PROJECT],
      body={
        "name" : parameters[self.PARAM_GROUP],
        "description" : "Network used for AppScale instances",
        "IPv4Range" : "10.240.0.0/16"
      }
    )
    response = request.execute(http=auth_http)
    AppScaleLogger.verbose(str(response), parameters[self.PARAM_VERBOSE])
    self.ensure_operation_succeeds(gce_service, auth_http, response,
      parameters[self.PARAM_PROJECT])
    return response['targetLink']
Пример #5
0
  def terminate_instances(self, parameters):
    """ Deletes the instances specified in 'parameters' running in Google
    Compute Engine.

    Args:
      parameters: A dict with keys for each parameter needed to connect to
        Google Compute Engine, and an additional key mapping to a list of
        instance names that should be deleted.
    """
    instance_ids = parameters[self.PARAM_INSTANCE_IDS]
    responses = []
    for instance_id in instance_ids:
      gce_service, credentials = self.open_connection(parameters)
      http = httplib2.Http()
      auth_http = credentials.authorize(http)
      request = gce_service.instances().delete(
        project=parameters[self.PARAM_PROJECT],
        zone=parameters[self.PARAM_ZONE],
        instance=instance_id
      )
      response = request.execute(http=auth_http)
      AppScaleLogger.verbose(str(response), parameters[self.PARAM_VERBOSE])
      responses.append(response)

    for response in responses:
      gce_service, credentials = self.open_connection(parameters)
      http = httplib2.Http()
      auth_http = credentials.authorize(http)
      self.ensure_operation_succeeds(gce_service, auth_http, response,
        parameters[self.PARAM_PROJECT])
Пример #6
0
  def create_firewall(self, parameters, network_url):
    """ Creates a new firewall in Google Compute Engine with the specified name,
    bound to the specified network.

    Args:
      parameters: A dict with keys for each parameter needed to connect to
        Google Compute Engine, and an additional key indicating the name of the
        firewall that we should create.
      network_url: A str containing the URL of the network that this new
        firewall should be applied to.
    """
    gce_service, credentials = self.open_connection(parameters)
    http = httplib2.Http()
    auth_http = credentials.authorize(http)
    request = gce_service.firewalls().insert(
      project=parameters[self.PARAM_PROJECT],
      body={
        "name" : parameters[self.PARAM_GROUP],
        "description" : "Firewall used for AppScale instances",
        "network" : network_url,
        "sourceRanges" : ["0.0.0.0/0"],
        "allowed" : [
          {"IPProtocol" : "tcp", "ports": ["1-65535"]},
          {"IPProtocol" : "udp", "ports": ["1-65535"]},
          {"IPProtocol" : "icmp"}
        ]
      }
    )
    response = request.execute(http=auth_http)
    AppScaleLogger.verbose(str(response), parameters[self.PARAM_VERBOSE])
    self.ensure_operation_succeeds(gce_service, auth_http, response,
      parameters[self.PARAM_PROJECT])
Пример #7
0
 def create_virtual_network(self, network_client, parameters, network_name,
                            subnet_name):
     """ Creates the network resources, such as Virtual network and Subnet.
 Args:
   network_client: A NetworkManagementClient instance.
   parameters:  A dict, containing all the parameters necessary to
     authenticate this user with Azure.
   network_name: The name to use for the Virtual Network resource.
   subnet_name: The name to use for the Subnet resource.
 Returns:
   A Subnet instance from the Virtual Network created.
 """
     group_name = parameters[self.PARAM_RESOURCE_GROUP]
     region = parameters[self.PARAM_ZONE]
     verbose = parameters[self.PARAM_VERBOSE]
     AppScaleLogger.verbose(
         "Creating/Updating the Virtual Network '{}'".format(network_name),
         verbose)
     address_space = AddressSpace(address_prefixes=['10.1.0.0/16'])
     subnet1 = Subnet(name=subnet_name, address_prefix='10.1.0.0/24')
     result = network_client.virtual_networks.create_or_update(
         group_name, network_name,
         VirtualNetwork(location=region,
                        address_space=address_space,
                        subnets=[subnet1]))
     self.sleep_until_update_operation_done(result, network_name, verbose)
     subnet = network_client.subnets.get(group_name, network_name,
                                         subnet_name)
     return subnet
Пример #8
0
  def does_address_exist(self, parameters):
    """ Queries Google Compute Engine to see if the specified static IP address
    exists for this user.

    Args:
      parameters: A dict with keys for each parameter needed to connect to
        Google Compute Engine, and an additional key indicating the name of the
        static IP address that we should check for existence.
    Returns:
      True if the named address exists, and False otherwise.
    """
    gce_service, credentials = self.open_connection(parameters)
    http = httplib2.Http()
    auth_http = credentials.authorize(http)
    request = gce_service.addresses().list(
      project=parameters[self.PARAM_PROJECT],
      filter="address eq {0}".format(parameters[self.PARAM_STATIC_IP]),
      region=parameters[self.PARAM_REGION]
    )
    response = request.execute(http=auth_http)
    AppScaleLogger.verbose(str(response), parameters[self.PARAM_VERBOSE])

    if 'items' in response:
      return True
    else:
      return False
Пример #9
0
 def sleep_until_delete_operation_done(self, result, resource_name,
                                       max_sleep, verbose):
     """ Sleeps until the delete operation for the resource is completed
 successfully.
 Args:
   result: An instance, of the AzureOperationPoller to poll for the status
     of the operation being performed.
   resource_name: The name of the resource being deleted.
   max_sleep: The maximum number of seconds to sleep for the resources to
     be deleted.
   verbose: A boolean indicating whether or not in verbose mode.
 """
     time_start = time.time()
     while not result.done():
         AppScaleLogger.verbose(
             "Waiting {0} second(s) for {1} to be deleted.".format(
                 self.SLEEP_TIME, resource_name), verbose)
         time.sleep(self.SLEEP_TIME)
         total_sleep_time = time.time() - time_start
         if total_sleep_time > max_sleep:
             AppScaleLogger.log(
                 "Waited {0} second(s) for {1} to be deleted. "
                 "Operation has timed out.".format(total_sleep_time,
                                                   resource_name))
             break
Пример #10
0
    def terminate_instances(self, parameters):
        """ Deletes the instances specified in 'parameters' running in Azure.
    Args:
      parameters: A dict, containing all the parameters necessary to
        authenticate this user with Azure.
    """
        credentials = self.open_connection(parameters)
        resource_group = parameters[self.PARAM_RESOURCE_GROUP]
        subscription_id = parameters[self.PARAM_SUBSCRIBER_ID]
        verbose = parameters[self.PARAM_VERBOSE]
        public_ips, private_ips, instance_ids = self.describe_instances(
            parameters)
        AppScaleLogger.verbose(
            "Terminating the vm instance/s '{}'".format(instance_ids), verbose)
        compute_client = ComputeManagementClient(credentials, subscription_id)
        threads = []
        for vm_name in instance_ids:
            thread = threading.Thread(target=self.delete_virtual_machine,
                                      args=(compute_client, resource_group,
                                            verbose, vm_name))
            thread.start()
            threads.append(thread)

        for x in threads:
            x.join()
Пример #11
0
  def create_network_interface(self, network_client, interface_name, ip_name,
                               subnet, parameters):
    """ Creates the Public IP Address resource and uses that to create the
    Network Interface.
    Args:
      network_client: A NetworkManagementClient instance.
      interface_name: The name to use for the Network Interface.
      ip_name: The name to use for the Public IP Address.
      subnet: The Subnet resource from the Virtual Network created.
      parameters:  A dict, containing all the parameters necessary to
        authenticate this user with Azure.
    """
    group_name = parameters[self.PARAM_RESOURCE_GROUP]
    region = parameters[self.PARAM_ZONE]
    verbose = parameters[self.PARAM_VERBOSE]
    AppScaleLogger.verbose("Creating/Updating the Public IP Address '{}'".
                           format(ip_name), verbose)
    ip_address = PublicIPAddress(
      location=region, public_ip_allocation_method=IPAllocationMethod.dynamic,
      idle_timeout_in_minutes=4)
    result = network_client.public_ip_addresses.create_or_update(
      group_name, ip_name, ip_address)
    self.sleep_until_update_operation_done(result, ip_name, verbose)
    public_ip_address = network_client.public_ip_addresses.get(group_name, ip_name)

    AppScaleLogger.verbose("Creating/Updating the Network Interface '{}'".
                           format(interface_name), verbose)
    network_interface_ip_conf = NetworkInterfaceIPConfiguration(
      name=interface_name, private_ip_allocation_method=IPAllocationMethod.dynamic,
      subnet=subnet, public_ip_address=PublicIPAddress(id=(public_ip_address.id)))

    result = network_client.network_interfaces.create_or_update(group_name,
      interface_name, NetworkInterface(location=region,
                                       ip_configurations=[network_interface_ip_conf]))
    self.sleep_until_update_operation_done(result, interface_name, verbose)
Пример #12
0
  def does_ssh_key_exist(self, parameters):
    """ Queries Google Compute Engine to see if the specified SSH key exists.

    Args:
      parameters: A dict with keys for each parameter needed to connect to
        Google Compute Engine. We don't have an additional key for the name of
        the SSH key, since we use the one in ~/.ssh.
    Returns:
      A tuple of two items. The first item is a bool that is True if
        our public key's contents are in GCE, and False otherwise, while
        the second item is the contents of all SSH keys stored in GCE.
    """
    our_public_ssh_key = None
    public_ssh_key_location = LocalState.LOCAL_APPSCALE_PATH + \
      parameters[self.PARAM_KEYNAME] + ".pub"
    with open(public_ssh_key_location) as file_handle:
      system_user = os.getenv('LOGNAME', default=pwd.getpwuid(os.getuid())[0])
      our_public_ssh_key = system_user + ":" + file_handle.read().rstrip()

    gce_service, credentials = self.open_connection(parameters)
    try:
      http = httplib2.Http()
      auth_http = credentials.authorize(http)
      request = gce_service.projects().get(
        project=parameters[self.PARAM_PROJECT])
      response = request.execute(http=auth_http)
      AppScaleLogger.verbose(str(response), parameters[self.PARAM_VERBOSE])

      if not 'items' in response['commonInstanceMetadata']:
        return False, ""

      metadata = response['commonInstanceMetadata']['items']
      if not metadata:
        return False, ""

      all_ssh_keys = ""
      for item in metadata:
        if item['key'] != 'sshKeys':
          continue

        # Now that we know there's one or more SSH keys, just make sure that
        # ours is in this list.
        all_ssh_keys = item['value']
        if our_public_ssh_key in all_ssh_keys:
          return True, all_ssh_keys

      return False, all_ssh_keys
    except errors.HttpError:
      return False, ""
Пример #13
0
 def sleep_until_update_operation_done(self, result, resource_name, verbose):
   """ Sleeps until the create/update operation for the resource is completed
     successfully.
     Args:
       result: An instance, of the AzureOperationPoller to poll for the status
         of the operation being performed.
       resource_name: The name of the resource being updated.
   """
   time_start = time.time()
   while not result.done():
     AppScaleLogger.verbose("Waiting {0} second(s) for {1} to be created/updated.".
                            format(self.SLEEP_TIME, resource_name), verbose)
     time.sleep(self.SLEEP_TIME)
     total_sleep_time = time.time() - time_start
     if total_sleep_time > self.MAX_SLEEP_TIME:
       AppScaleLogger.log("Waited {0} second(s) for {1} to be created/updated. "
         "Operation has timed out.".format(total_sleep_time, resource_name))
       break
Пример #14
0
    def create_network_interface(self, network_client, interface_name, ip_name,
                                 subnet, parameters):
        """ Creates the Public IP Address resource and uses that to create the
    Network Interface.
    Args:
      network_client: A NetworkManagementClient instance.
      interface_name: The name to use for the Network Interface.
      ip_name: The name to use for the Public IP Address.
      subnet: The Subnet resource from the Virtual Network created.
      parameters:  A dict, containing all the parameters necessary to
        authenticate this user with Azure.
    """
        group_name = parameters[self.PARAM_RESOURCE_GROUP]
        region = parameters[self.PARAM_ZONE]
        verbose = parameters[self.PARAM_VERBOSE]
        AppScaleLogger.verbose(
            "Creating/Updating the Public IP Address '{}'".format(ip_name),
            verbose)
        ip_address = PublicIPAddress(
            location=region,
            public_ip_allocation_method=IPAllocationMethod.dynamic,
            idle_timeout_in_minutes=4)
        result = network_client.public_ip_addresses.create_or_update(
            group_name, ip_name, ip_address)
        self.sleep_until_update_operation_done(result, ip_name, verbose)
        public_ip_address = network_client.public_ip_addresses.get(
            group_name, ip_name)

        AppScaleLogger.verbose(
            "Creating/Updating the Network Interface '{}'".format(
                interface_name), verbose)
        network_interface_ip_conf = NetworkInterfaceIPConfiguration(
            name=interface_name,
            private_ip_allocation_method=IPAllocationMethod.dynamic,
            subnet=subnet,
            public_ip_address=PublicIPAddress(id=(public_ip_address.id)))

        result = network_client.network_interfaces.create_or_update(
            group_name, interface_name,
            NetworkInterface(location=region,
                             ip_configurations=[network_interface_ip_conf]))
        self.sleep_until_update_operation_done(result, interface_name, verbose)
Пример #15
0
  def create_ssh_key(self, parameters, all_ssh_keys):
    """ Creates a new SSH key in Google Compute Engine with the contents of
    our newly generated public key.

    Args:
      parameters: A dict with keys for each parameter needed to connect to
        Google Compute Engine.
      all_ssh_keys: A str that contains all of the SSH keys that are
        currently passed in to GCE instances.
    """
    our_public_ssh_key = None
    public_ssh_key_location = LocalState.LOCAL_APPSCALE_PATH + \
      parameters[self.PARAM_KEYNAME] + ".pub"
    with open(public_ssh_key_location) as file_handle:
      system_user = os.getenv('LOGNAME', default=pwd.getpwuid(os.getuid())[0])
      public_ssh_key = file_handle.read().rstrip()
      our_public_ssh_keys = "{system_user}:{key}\nroot:{key}".format(
                            system_user=system_user, key=public_ssh_key)

    if all_ssh_keys:
      new_all_ssh_keys = our_public_ssh_keys + "\n" + all_ssh_keys
    else:
      new_all_ssh_keys = our_public_ssh_key

    gce_service, credentials = self.open_connection(parameters)
    http = httplib2.Http()
    auth_http = credentials.authorize(http)
    request = gce_service.projects().setCommonInstanceMetadata(
      project=parameters[self.PARAM_PROJECT],
      body={
        "kind": "compute#metadata",
        "items": [{
          "key": "sshKeys",
          "value": new_all_ssh_keys
        }]
      }
    )
    response = request.execute(http=auth_http)
    AppScaleLogger.verbose(str(response), parameters[self.PARAM_VERBOSE])
    self.ensure_operation_succeeds(gce_service, auth_http, response,
      parameters[self.PARAM_PROJECT])
Пример #16
0
  def does_image_exist(self, parameters):
    """ Queries Google Compute Engine to see if the specified image exists for
    this user.

    Args:
      parameters: A dict with keys for each parameter needed to connect to
        Google Compute Engine, and an additional key indicating the name of the
        image that we should check for existence.
    Returns:
      True if the named image exists, and False otherwise.
    """
    gce_service, credentials = self.open_connection(parameters)
    try:
      http = httplib2.Http()
      auth_http = credentials.authorize(http)
      request = gce_service.images().get(project=parameters[self.PARAM_PROJECT],
        image=parameters[self.PARAM_IMAGE_ID])
      response = request.execute(http=auth_http)
      AppScaleLogger.verbose(str(response), parameters[self.PARAM_VERBOSE])
      return True
    except errors.HttpError:
      return False
Пример #17
0
 def sleep_until_update_operation_done(self, result, resource_name,
                                       verbose):
     """ Sleeps until the create/update operation for the resource is completed
   successfully.
   Args:
     result: An instance, of the AzureOperationPoller to poll for the status
       of the operation being performed.
     resource_name: The name of the resource being updated.
 """
     time_start = time.time()
     while not result.done():
         AppScaleLogger.verbose(
             "Waiting {0} second(s) for {1} to be created/updated.".format(
                 self.SLEEP_TIME, resource_name), verbose)
         time.sleep(self.SLEEP_TIME)
         total_sleep_time = time.time() - time_start
         if total_sleep_time > self.MAX_SLEEP_TIME:
             AppScaleLogger.log(
                 "Waited {0} second(s) for {1} to be created/updated. "
                 "Operation has timed out.".format(total_sleep_time,
                                                   resource_name))
             break
Пример #18
0
 def sleep_until_delete_operation_done(self, result, resource_name,
                                       max_sleep, verbose):
   """ Sleeps until the delete operation for the resource is completed
   successfully.
   Args:
     result: An instance, of the AzureOperationPoller to poll for the status
       of the operation being performed.
     resource_name: The name of the resource being deleted.
     max_sleep: The maximum number of seconds to sleep for the resources to
       be deleted.
     verbose: A boolean indicating whether or not in verbose mode.
   """
   time_start = time.time()
   while not result.done():
     AppScaleLogger.verbose("Waiting {0} second(s) for {1} to be deleted.".
                            format(self.SLEEP_TIME, resource_name), verbose)
     time.sleep(self.SLEEP_TIME)
     total_sleep_time = time.time() - time_start
     if total_sleep_time > max_sleep:
       AppScaleLogger.log("Waited {0} second(s) for {1} to be deleted. "
         "Operation has timed out.".format(total_sleep_time, resource_name))
       break
Пример #19
0
  def describe_instances(self, parameters, pending=False):
    """ Queries Google Compute Engine to see which instances are currently
    running, and retrieve information about their public and private IPs.

    Args:
      parameters: A dict with keys for each parameter needed to connect to
        Google Compute Engine.
      pending: Boolean if we should show pending instances.
    Returns:
      A tuple of the form (public_ips, private_ips, instance_ids), where each
        member is a list. Items correspond to each other across these lists,
        so a caller is guaranteed that item X in each list belongs to the same
        virtual machine.
    """
    gce_service, credentials = self.open_connection(parameters)
    http = httplib2.Http()
    auth_http = credentials.authorize(http)
    request = gce_service.instances().list(
      project=parameters[self.PARAM_PROJECT],
      filter="name eq {group}-.*".format(group=parameters[self.PARAM_GROUP]),
      zone=parameters[self.PARAM_ZONE]
    )
    response = request.execute(http=auth_http)
    AppScaleLogger.verbose(str(response), parameters[self.PARAM_VERBOSE])

    instance_ids = []
    public_ips = []
    private_ips = []

    if response and 'items' in response:
      instances = response['items']
      for instance in instances:
        if instance['status'] == "RUNNING":
          instance_ids.append(instance['name'])
          network_interface = instance['networkInterfaces'][0]
          public_ips.append(network_interface['accessConfigs'][0]['natIP'])
          private_ips.append(network_interface['networkIP'])

    return public_ips, private_ips, instance_ids
Пример #20
0
  def delete_firewall(self, parameters):
    """ Deletes a firewall in Google Compute Engine with the specified name.

    Callers should not invoke this method until they are certain that no
    instances are using the specified firewall, or this method will fail.

    Args:
      parameters: A dict with keys for each parameter needed to connect to
        Google Compute Engine, and an additional key indicating the name of the
        firewall that we should create.
    """
    gce_service, credentials = self.open_connection(parameters)
    http = httplib2.Http()
    auth_http = credentials.authorize(http)
    request = gce_service.firewalls().delete(
      project=parameters[self.PARAM_PROJECT],
      firewall=parameters[self.PARAM_GROUP]
    )
    response = request.execute(http=auth_http)
    AppScaleLogger.verbose(str(response), parameters[self.PARAM_VERBOSE])
    self.ensure_operation_succeeds(gce_service, auth_http, response,
      parameters[self.PARAM_PROJECT])
Пример #21
0
  def assert_credentials_are_valid(self, parameters):
    """Contacts GCE to see if the given credentials are valid.

    Args:
      parameters: A dict containing the credentials necessary to interact with
      GCE.

    Raises:
      AgentConfigurationException: If an error is encountered during
      authentication.
    """
    gce_service, credentials = self.open_connection(parameters)
    try:
      http = httplib2.Http()
      auth_http = credentials.authorize(http)
      request = gce_service.instances().list(project=parameters
        [self.PARAM_PROJECT], zone=parameters[self.PARAM_ZONE])
      response = request.execute(http=auth_http)
      AppScaleLogger.verbose(str(response), parameters[self.PARAM_VERBOSE])
      return True
    except errors.HttpError as e:
      error_message = json.loads(e.content)['error']['message']
      raise AgentConfigurationException(error_message)
Пример #22
0
  def does_disk_exist(self, parameters, disk):
    """ Queries Google Compute Engine to see if the specified persistent disk
    exists for this user.

    Args:
      parameters: A dict with keys for each parameter needed to connect to
        Google Compute Engine.
      disk: A str containing the name of the disk that we should check for
        existence.
    Returns:
      True if the named persistent disk exists, and False otherwise.
    """
    gce_service, credentials = self.open_connection(parameters)
    try:
      http = httplib2.Http()
      auth_http = credentials.authorize(http)
      request = gce_service.disks().get(project=parameters[self.PARAM_PROJECT],
        disk=disk, zone=parameters[self.PARAM_ZONE])
      response = request.execute(http=auth_http)
      AppScaleLogger.verbose(str(response), parameters[self.PARAM_VERBOSE])
      return True
    except errors.HttpError:
      return False
Пример #23
0
  def delete_access_config(self, parameters, instance_id):
    """ Instructs Google Compute Engine to remove the public IP address from
    the named instance.

    Args:
      parameters: A dict with keys for each parameter needed to connect to
        Google Compute Engine, and an additional key mapping to a list of
        instance names that should be deleted.
      instance_id: A str naming the running instance that the new public IP
        address should be added to.
    """
    gce_service, credentials = self.open_connection(parameters)
    http = httplib2.Http()
    auth_http = credentials.authorize(http)
    request = gce_service.instances().deleteAccessConfig(
      project=parameters[self.PARAM_PROJECT],
      accessConfig="External NAT",
      instance=instance_id,
      networkInterface="nic0",
      zone=parameters[self.PARAM_ZONE]
    )
    response = request.execute(http=auth_http)
    AppScaleLogger.verbose(str(response), parameters[self.PARAM_VERBOSE])
Пример #24
0
  def create_scratch_disk(self, parameters):
    """ Creates a disk from a given machine image.

    GCE does not support scratch disks on API version v1 and higher. We create
    a persistent disk upon creation to act like one to keep the abstraction used
    in other infrastructures.

    Args:
      parameters: A dict with keys for each parameter needed to connect to
        Google Compute Engine.
    Returns:
      A str, the url to the disk to use.
    """
    gce_service, credentials = self.open_connection(parameters)
    http = httplib2.Http()
    auth_http = credentials.authorize(http)
    disk_name = self.generate_disk_name(parameters)
    project_url = '{0}{1}'.format(self.GCE_URL, 
      parameters[self.PARAM_PROJECT])
    source_image_url = '{0}{1}/global/images/{2}'.format(self.GCE_URL,
      parameters[self.PARAM_PROJECT], parameters[self.PARAM_IMAGE_ID])
    request = gce_service.disks().insert(
      project=parameters[self.PARAM_PROJECT],
      zone=parameters[self.PARAM_ZONE],
      body={
        'name':disk_name 
      },
      sourceImage=source_image_url
    )
    response = request.execute(http=auth_http)
    AppScaleLogger.verbose(str(response), parameters[self.PARAM_VERBOSE])
    self.ensure_operation_succeeds(gce_service, auth_http, response,
      parameters[self.PARAM_PROJECT])

    disk_url = "{0}/zones/{1}/disks/{2}".format(
      project_url, parameters[self.PARAM_ZONE], disk_name)
    return disk_url
Пример #25
0
  def terminate_instances(self, parameters):
    """ Deletes the instances specified in 'parameters' running in Azure.
    Args:
      parameters: A dict, containing all the parameters necessary to
        authenticate this user with Azure.
    """
    credentials = self.open_connection(parameters)
    resource_group = parameters[self.PARAM_RESOURCE_GROUP]
    subscription_id = parameters[self.PARAM_SUBSCRIBER_ID]
    verbose = parameters[self.PARAM_VERBOSE]
    public_ips, private_ips, instance_ids = self.describe_instances(parameters)
    AppScaleLogger.verbose("Terminating the vm instance/s '{}'".
                           format(instance_ids), verbose)
    compute_client = ComputeManagementClient(credentials, subscription_id)
    threads = []
    for vm_name in instance_ids:
      thread = threading.Thread(target=self.delete_virtual_machine,
                                args=(compute_client, resource_group, verbose,
                                      vm_name))
      thread.start()
      threads.append(thread)

    for x in threads:
      x.join()
Пример #26
0
  def detach_disk(self, parameters, disk_name, instance_id):
    """ Detaches the persistent disk specified in 'disk_name' from the named
    instance.

    Args:
      parameters: A dict with keys for each parameter needed to connect to
        Google Compute Engine.
      disk_name: A str naming the persistent disk to detach.
      instance_id: A str naming the id of the instance that the disk should be
        detached from.
    """
    gce_service, credentials = self.open_connection(parameters)
    http = httplib2.Http()
    auth_http = credentials.authorize(http)
    project_id = parameters[self.PARAM_PROJECT]
    request = gce_service.instances().detachDisk(
      project=project_id,
      zone=parameters[self.PARAM_ZONE],
      instance=instance_id,
      deviceName='sdb')
    response = request.execute(http=auth_http)
    AppScaleLogger.verbose(str(response), parameters[self.PARAM_VERBOSE])
    self.ensure_operation_succeeds(gce_service, auth_http, response,
      parameters[self.PARAM_PROJECT])
Пример #27
0
    def create_virtual_machine(self, credentials, network_client, network_id,
                               parameters, vm_network_name):
        """ Creates an Azure virtual machine using the network interface created.
    Args:
      credentials: A ServicePrincipalCredentials instance, that can be used to
        access or create any resources.
      network_client: A NetworkManagementClient instance.
      network_id: The network id of the network interface created.
      parameters: A dict, containing all the parameters necessary to
        authenticate this user with Azure.
      vm_network_name: The name of the virtual machine to use.
    """
        resource_group = parameters[self.PARAM_RESOURCE_GROUP]
        storage_account = parameters[self.PARAM_STORAGE_ACCOUNT]
        zone = parameters[self.PARAM_ZONE]
        verbose = parameters[self.PARAM_VERBOSE]
        AppScaleLogger.verbose(
            "Creating a Virtual Machine '{}'".format(vm_network_name), verbose)
        subscription_id = parameters[self.PARAM_SUBSCRIBER_ID]
        azure_instance_type = parameters[self.PARAM_INSTANCE_TYPE]
        compute_client = ComputeManagementClient(credentials, subscription_id)

        keyname = parameters[self.PARAM_KEYNAME]
        private_key_path = LocalState.LOCAL_APPSCALE_PATH + keyname
        public_key_path = private_key_path + ".pub"

        with open(public_key_path, 'r') as pub_ssh_key_fd:
            pub_ssh_key = pub_ssh_key_fd.read()

        key_path = "/home/{}/.ssh/authorized_keys".format(self.ADMIN_USERNAME)
        public_keys = [SshPublicKey(path=key_path, key_data=pub_ssh_key)]
        ssh_config = SshConfiguration(public_keys=public_keys)
        linux_config = LinuxConfiguration(disable_password_authentication=True,
                                          ssh=ssh_config)
        os_profile = OSProfile(admin_username=self.ADMIN_USERNAME,
                               computer_name=vm_network_name,
                               linux_configuration=linux_config)

        hardware_profile = HardwareProfile(vm_size=azure_instance_type)

        network_profile = NetworkProfile(
            network_interfaces=[NetworkInterfaceReference(id=network_id)])

        virtual_hd = VirtualHardDisk(
            uri='https://{0}.blob.core.windows.net/vhds/{1}.vhd'.format(
                storage_account, vm_network_name))

        image_hd = VirtualHardDisk(uri=parameters[self.PARAM_IMAGE_ID])
        os_type = OperatingSystemTypes.linux
        os_disk = OSDisk(os_type=os_type,
                         caching=CachingTypes.read_write,
                         create_option=DiskCreateOptionTypes.from_image,
                         name=vm_network_name,
                         vhd=virtual_hd,
                         image=image_hd)

        compute_client.virtual_machines.create_or_update(
            resource_group, vm_network_name,
            VirtualMachine(location=zone,
                           os_profile=os_profile,
                           hardware_profile=hardware_profile,
                           network_profile=network_profile,
                           storage_profile=StorageProfile(os_disk=os_disk)))

        # Sleep until an IP address gets associated with the VM.
        while True:
            public_ip_address = network_client.public_ip_addresses.get(
                resource_group, vm_network_name)
            if public_ip_address.ip_address:
                AppScaleLogger.log('Azure VM is available at {}'.format(
                    public_ip_address.ip_address))
                break
            AppScaleLogger.verbose(
                "Waiting {} second(s) for IP address to be "
                "available".format(self.SLEEP_TIME), verbose)
            time.sleep(self.SLEEP_TIME)
Пример #28
0
  def create_virtual_machine(self, credentials, network_client, network_id,
                             parameters, vm_network_name):
    """ Creates an Azure virtual machine using the network interface created.
    Args:
      credentials: A ServicePrincipalCredentials instance, that can be used to
        access or create any resources.
      network_client: A NetworkManagementClient instance.
      network_id: The network id of the network interface created.
      parameters: A dict, containing all the parameters necessary to
        authenticate this user with Azure.
      vm_network_name: The name of the virtual machine to use.
    """
    resource_group = parameters[self.PARAM_RESOURCE_GROUP]
    storage_account = parameters[self.PARAM_STORAGE_ACCOUNT]
    zone = parameters[self.PARAM_ZONE]
    verbose = parameters[self.PARAM_VERBOSE]
    AppScaleLogger.verbose("Creating a Virtual Machine '{}'".
                           format(vm_network_name), verbose)
    subscription_id = parameters[self.PARAM_SUBSCRIBER_ID]
    azure_instance_type = parameters[self.PARAM_INSTANCE_TYPE]
    compute_client = ComputeManagementClient(credentials, subscription_id)

    keyname = parameters[self.PARAM_KEYNAME]
    private_key_path = LocalState.LOCAL_APPSCALE_PATH + keyname
    public_key_path = private_key_path + ".pub"

    with open(public_key_path, 'r') as pub_ssh_key_fd:
      pub_ssh_key = pub_ssh_key_fd.read()

    key_path = "/home/{}/.ssh/authorized_keys".format(self.ADMIN_USERNAME)
    public_keys = [SshPublicKey(path=key_path, key_data=pub_ssh_key)]
    ssh_config = SshConfiguration(public_keys=public_keys)
    linux_config = LinuxConfiguration(disable_password_authentication=True,
                                      ssh=ssh_config)
    os_profile = OSProfile(admin_username=self.ADMIN_USERNAME,
                           computer_name=vm_network_name,
                           linux_configuration=linux_config)

    hardware_profile = HardwareProfile(vm_size=azure_instance_type)

    network_profile = NetworkProfile(
      network_interfaces=[NetworkInterfaceReference(id=network_id)])

    virtual_hd = VirtualHardDisk(
      uri='https://{0}.blob.core.windows.net/vhds/{1}.vhd'.
        format(storage_account, vm_network_name))

    image_hd = VirtualHardDisk(uri=parameters[self.PARAM_IMAGE_ID])
    os_type = OperatingSystemTypes.linux
    os_disk = OSDisk(os_type=os_type, caching=CachingTypes.read_write,
                     create_option=DiskCreateOptionTypes.from_image,
                     name=vm_network_name, vhd=virtual_hd, image=image_hd)

    compute_client.virtual_machines.create_or_update(
      resource_group, vm_network_name, VirtualMachine(location=zone,
                                                      os_profile=os_profile,
                                                      hardware_profile=hardware_profile,
                                                      network_profile=network_profile,
                                                      storage_profile=StorageProfile(
                                                        os_disk=os_disk)))

    # Sleep until an IP address gets associated with the VM.
    while True:
      public_ip_address = network_client.public_ip_addresses.get(resource_group,
                                                                 vm_network_name)
      if public_ip_address.ip_address:
        AppScaleLogger.log('Azure VM is available at {}'.
                           format(public_ip_address.ip_address))
        break
      AppScaleLogger.verbose("Waiting {} second(s) for IP address to be "
        "available".format(self.SLEEP_TIME), verbose)
      time.sleep(self.SLEEP_TIME)
Пример #29
0
  def gather_logs(cls, options):
    """Collects logs from each machine in the currently running AppScale
    deployment.

    Args:
      options: A Namespace that has fields for each parameter that can be
        passed in via the command-line interface.
    """
    location = os.path.abspath(options.location)
    # First, make sure that the place we want to store logs doesn't
    # already exist.
    if os.path.exists(location):
      raise AppScaleException("Can't gather logs, as the location you " + \
        "specified, {}, already exists.".format(location))

    load_balancer_ip = LocalState.get_host_with_role(
      options.keyname, 'load_balancer')
    secret = LocalState.get_secret_key(options.keyname)
    acc = AppControllerClient(load_balancer_ip, secret)

    try:
      all_ips = acc.get_all_public_ips()
    except socket.error:  # Occurs when the AppController has failed.
      AppScaleLogger.warn("Couldn't get an up-to-date listing of the " + \
        "machines in this AppScale deployment. Using our locally cached " + \
        "info instead.")
      all_ips = LocalState.get_all_public_ips(options.keyname)

    # Get information about roles and public IPs
    # for creating navigation symlinks in gathered logs
    try:
      nodes_info = acc.get_role_info()
    except socket.error:  # Occurs when the AppController has failed.
      AppScaleLogger.warn("Couldn't get an up-to-date nodes info. "
                          "Using our locally cached info instead.")
      nodes_info = LocalState.get_local_nodes_info(options.keyname)
    nodes_dict = {node['public_ip']: node for node in nodes_info}

    # do the mkdir after we get the secret key, so that a bad keyname will
    # cause the tool to crash and not create this directory
    os.mkdir(location)

    # make dir for private IP navigation links
    private_ips_dir = os.path.join(location, 'symlinks', 'private-ips')
    utils.mkdir(private_ips_dir)

    # The log paths that we collect logs from.
    log_paths = [
      {'remote': '/opt/cassandra/cassandra/logs/*', 'local': 'cassandra'},
      {'remote': '/var/log/appscale'},
      {'remote': '/var/log/haproxy.log*'},
      {'remote': '/var/log/kern.log*'},
      {'remote': '/var/log/nginx'},
      {'remote': '/var/log/rabbitmq/*', 'local': 'rabbitmq'},
      {'remote': '/var/log/syslog*'},
      {'remote': '/var/log/zookeeper'}
    ]

    failures = False
    for public_ip in all_ips:
      # Get the logs from each node, and store them in our local directory
      local_dir = os.path.join(location, public_ip)
      utils.mkdir(local_dir)
      local_link = os.path.join('..', '..', public_ip)

      # Create symlinks for easier navigation in gathered logs
      node_info = nodes_dict.get(public_ip)
      if node_info:
        private_ip_dir = os.path.join(private_ips_dir, node_info["private_ip"])
        os.symlink(local_link, private_ip_dir)
        for role in node_info['roles']:
          role_dir = os.path.join(location, 'symlinks', role)
          utils.mkdir(role_dir)
          os.symlink(local_link, os.path.join(role_dir, public_ip))

      for log_path in log_paths:
        sub_dir = local_dir

        if 'local' in log_path:
          sub_dir = os.path.join(local_dir, log_path['local'])
          utils.mkdir(sub_dir)

        try:
          RemoteHelper.scp_remote_to_local(
            public_ip, options.keyname, log_path['remote'], sub_dir
          )
        except ShellException as shell_exception:
          failures = True
          AppScaleLogger.warn('Unable to collect logs from {} for host {}'.
                              format(log_path['remote'], public_ip))
          AppScaleLogger.verbose(
            'Encountered exception: {}'.format(str(shell_exception)))

    if failures:
      AppScaleLogger.log("Done copying to {}. There were failures while "
                         "collecting AppScale logs.".format(location))
    else:
      AppScaleLogger.success("Successfully collected all AppScale logs into "
                             "{}".format(location))
Пример #30
0
  def run_instances(self, count, parameters, security_configured):
    """ Starts 'count' instances in Google Compute Engine, and returns once they
    have been started.

    Callers should create a network and attach a firewall to it before using
    this method, or the newly created instances will not have a network and
    firewall to attach to (and thus this method will fail).

    Args:
      count: An int that specifies how many virtual machines should be started.
      parameters: A dict with keys for each parameter needed to connect to
        Google Compute Engine.
      security_configured: Unused, as we assume that the network and firewall
        has already been set up.
    """
    project_id = parameters[self.PARAM_PROJECT]
    image_id = parameters[self.PARAM_IMAGE_ID]
    instance_type = parameters[self.PARAM_INSTANCE_TYPE]
    keyname = parameters[self.PARAM_KEYNAME]
    group = parameters[self.PARAM_GROUP]
    zone = parameters[self.PARAM_ZONE]

    AppScaleLogger.log("Starting {0} machines with machine id {1}, with " \
      "instance type {2}, keyname {3}, in security group {4}, in zone {5}" \
      .format(count, image_id, instance_type, keyname, group, zone))

    # First, see how many instances are running and what their info is.
    start_time = datetime.datetime.now()
    active_public_ips, active_private_ips, active_instances = \
      self.describe_instances(parameters)

    # Construct URLs
    image_url = '{0}{1}/global/images/{2}'.format(self.GCE_URL, project_id,
      image_id)
    project_url = '{0}{1}'.format(self.GCE_URL, project_id)
    machine_type_url = '{0}/zones/{1}/machineTypes/{2}'.format(project_url,
      zone, instance_type)
    network_url = '{0}/global/networks/{1}'.format(project_url, group)

    # Construct the request body
    for index in range(count):
      disk_url = self.create_scratch_disk(parameters)
      instances = {
        # Truncate the name down to the first 62 characters, since GCE doesn't
        # let us use arbitrarily long instance names.
        'name': '{group}-{uuid}'.format(group=group, uuid=uuid.uuid4())[:62],
        'machineType': machine_type_url,
        'disks':[{
          'source': disk_url,
          'boot': 'true',
          'type': 'PERSISTENT'
        }],
        'image': image_url,
        'networkInterfaces': [{
          'accessConfigs': [{
            'type': 'ONE_TO_ONE_NAT',
            'name': 'External NAT'
           }],
          'network': network_url
        }],
        'serviceAccounts': [{
             'email': self.DEFAULT_SERVICE_EMAIL,
             'scopes': [self.GCE_SCOPE]
        }]
      }

      # Create the instance
      gce_service, credentials = self.open_connection(parameters)
      http = httplib2.Http()
      auth_http = credentials.authorize(http)
      request = gce_service.instances().insert(
           project=project_id, body=instances, zone=zone)
      response = request.execute(http=auth_http)
      AppScaleLogger.verbose(str(response), parameters[self.PARAM_VERBOSE])
      self.ensure_operation_succeeds(gce_service, auth_http, response,
        parameters[self.PARAM_PROJECT])
    
    instance_ids = []
    public_ips = []
    private_ips = []
    end_time = datetime.datetime.now() + datetime.timedelta(0,
      self.MAX_VM_CREATION_TIME)
    now = datetime.datetime.now()

    while now < end_time:
      AppScaleLogger.log("Waiting for your instances to start...")
      instance_info = self.describe_instances(parameters)
      public_ips = instance_info[0]
      private_ips = instance_info[1]
      instance_ids = instance_info[2]
      public_ips = self.diff(public_ips, active_public_ips)
      private_ips = self.diff(private_ips, active_private_ips)
      instance_ids = self.diff(instance_ids, active_instances)
      if count == len(public_ips):
        break
      time.sleep(self.SLEEP_TIME)
      now = datetime.datetime.now()

    if not public_ips:
      self.handle_failure('No public IPs were able to be procured '
                          'within the time limit')

    if len(public_ips) != count:
      for index in range(0, len(public_ips)):
        if public_ips[index] == '0.0.0.0':
          instance_to_term = instance_ids[index]
          AppScaleLogger.log('Instance {0} failed to get a public IP address'\
                  'and is being terminated'.format(instance_to_term))
          self.terminate_instances([instance_to_term])

    end_time = datetime.datetime.now()
    total_time = end_time - start_time
    AppScaleLogger.log("Started {0} on-demand instances in {1} seconds" \
      .format(count, total_time.seconds))
    return instance_ids, public_ips, private_ips
Пример #31
0
  def run_instances(cls, options):
    """Starts a new AppScale deployment with the parameters given.

    Args:
      options: A Namespace that has fields for each parameter that can be
        passed in via the command-line interface.
    Raises:
      AppControllerException: If the AppController on the head node crashes.
        When this occurs, the message in the exception contains the reason why
        the AppController crashed.
      BadConfigurationException: If the user passes in options that are not
        sufficient to start an AppScale deployment (e.g., running on EC2 but
        not specifying the AMI to use), or if the user provides us
        contradictory options (e.g., running on EC2 but not specifying EC2
        credentials).
    """
    LocalState.make_appscale_directory()
    LocalState.ensure_appscale_isnt_running(options.keyname, options.force)
    node_layout = NodeLayout(options)

    if options.infrastructure:
      if (not options.test and not options.force and
          not (options.disks or node_layout.are_disks_used())):
        LocalState.ensure_user_wants_to_run_without_disks()

    reduced_version = '.'.join(x for x in APPSCALE_VERSION.split('.')[:2])
    AppScaleLogger.log("Starting AppScale " + reduced_version)

    my_id = str(uuid.uuid4())
    AppScaleLogger.remote_log_tools_state(options, my_id, "started",
      APPSCALE_VERSION)

    head_node = node_layout.head_node()
    # Start VMs in cloud via cloud agent.
    if options.infrastructure:
      node_layout = RemoteHelper.start_all_nodes(options, node_layout)

      # Enables root logins and SSH access on the head node.
      RemoteHelper.enable_root_ssh(options, head_node.public_ip)
    AppScaleLogger.verbose("Node Layout: {}".format(node_layout.to_list()))

    # Ensure all nodes are compatible.
    RemoteHelper.ensure_machine_is_compatible(
      head_node.public_ip, options.keyname)

    # Use rsync to move custom code into the deployment.
    if options.rsync_source:
      AppScaleLogger.log("Copying over local copy of AppScale from {0}".
        format(options.rsync_source))
      RemoteHelper.rsync_files(head_node.public_ip, options.keyname,
                               options.rsync_source)

    # Start services on head node.
    RemoteHelper.start_head_node(options, my_id, node_layout)

    # Write deployment metadata to disk (facilitates SSH operations, etc.)
    db_master = node_layout.db_master().private_ip
    head_node = node_layout.head_node().public_ip
    LocalState.update_local_metadata(options, db_master, head_node)

    # Copy the locations.json to the head node
    RemoteHelper.copy_local_metadata(node_layout.head_node().public_ip,
                                     options.keyname)

    # Wait for services on head node to start.
    secret_key = LocalState.get_secret_key(options.keyname)
    acc = AppControllerClient(head_node, secret_key)
    try:
      while not acc.is_initialized():
        AppScaleLogger.log('Waiting for head node to initialize...')
        # This can take some time in particular the first time around, since
        # we will have to initialize the database.
        time.sleep(cls.SLEEP_TIME*3)
    except socket.error as socket_error:
      AppScaleLogger.warn('Unable to initialize AppController: {}'.
                          format(socket_error.message))
      message = RemoteHelper.collect_appcontroller_crashlog(
        head_node, options.keyname)
      raise AppControllerException(message)

    # Set up admin account.
    try:
      # We don't need to have any exception information here: we do expect
      # some anyway while the UserAppServer is coming up.
      acc.does_user_exist("non-existent-user", True)
    except Exception:
      AppScaleLogger.log('UserAppServer not ready yet. Retrying ...')
      time.sleep(cls.SLEEP_TIME)

    if options.admin_user and options.admin_pass:
      AppScaleLogger.log("Using the provided admin username/password")
      username, password = options.admin_user, options.admin_pass
    elif options.test:
      AppScaleLogger.log("Using default admin username/password")
      username, password = LocalState.DEFAULT_USER, LocalState.DEFAULT_PASSWORD
    else:
      username, password = LocalState.get_credentials()

    RemoteHelper.create_user_accounts(username, password, head_node,
                                      options.keyname)
    acc.set_admin_role(username, 'true', cls.ADMIN_CAPABILITIES)

    # Wait for machines to finish loading and AppScale Dashboard to be deployed.
    RemoteHelper.wait_for_machines_to_finish_loading(head_node, options.keyname)

    try:
      login_host = acc.get_property('login')['login']
    except KeyError:
      raise AppControllerException('login property not found')

    RemoteHelper.sleep_until_port_is_open(
      login_host, RemoteHelper.APP_DASHBOARD_PORT)

    AppScaleLogger.success("AppScale successfully started!")
    AppScaleLogger.success(
      'View status information about your AppScale deployment at '
      'http://{}:{}'.format(login_host, RemoteHelper.APP_DASHBOARD_PORT))
    AppScaleLogger.remote_log_tools_state(options, my_id,
      "finished", APPSCALE_VERSION)
Пример #32
0
  def terminate_instances(cls, options):
    """Stops all services running in an AppScale deployment, and in cloud
    deployments, also powers off the instances previously spawned.

    Raises:
      AppScaleException: If AppScale is not running, and thus can't be
      terminated.
    """
    try:
      infrastructure = LocalState.get_infrastructure(options.keyname)
    except IOError:
      raise AppScaleException("Cannot find AppScale's configuration for keyname {0}".
        format(options.keyname))

    if infrastructure == "xen" and options.terminate:
      raise AppScaleException("Terminate option is invalid for cluster mode.")

    if infrastructure == "xen" or not options.terminate:
      # We are in cluster mode: let's check if AppScale is running.
      if not os.path.exists(LocalState.get_secret_key_location(options.keyname)):
        raise AppScaleException("AppScale is not running with the keyname {0}".
          format(options.keyname))

    # Stop gracefully the AppScale deployment.
    try:
      RemoteHelper.terminate_virtualized_cluster(options.keyname,
                                                 options.clean)
    except (IOError, AppScaleException, AppControllerException,
            BadConfigurationException) as e:
      if not (infrastructure in InfrastructureAgentFactory.VALID_AGENTS and
            options.terminate):
        raise

      if options.test:
        AppScaleLogger.warn(e)
      else:
        AppScaleLogger.verbose(e)
        if isinstance(e, AppControllerException):
          response = raw_input(
            'AppScale may not have shut down properly, are you sure you want '
            'to continue terminating? (y/N) ')
        else:
          response = raw_input(
            'AppScale could not find the configuration files for this '
            'deployment, are you sure you want to continue terminating? '
            '(y/N) ')
        if response.lower() not in ['y', 'yes']:
          raise AppScaleException("Cancelled cloud termination.")


    # And if we are on a cloud infrastructure, terminate instances if
    # asked.
    if (infrastructure in InfrastructureAgentFactory.VALID_AGENTS and
          options.terminate):
      RemoteHelper.terminate_cloud_infrastructure(options.keyname)
    elif infrastructure in InfrastructureAgentFactory.VALID_AGENTS and not \
        options.terminate:
      AppScaleLogger.log("AppScale did not terminate any of your cloud "
                         "instances, to terminate them run 'appscale "
                         "down --terminate'")
    if options.clean:
      LocalState.clean_local_metadata(keyname=options.keyname)