Пример #1
0
  def rsync_files(cls, host, keyname, local_appscale_dir, is_verbose):
    """Copies over an AppScale source directory from this machine to the
    specified host.

    Args:
      host: A str representing a host that should be accessible from this
        machine.
      keyname: A str representing the name of the SSH keypair that can log into
        the specified machine.
      local_appscale_dir: A str representing the path on the local filesystem
        where the AppScale source to copy over can be found.
      is_verbose: A bool that indicates if we should print the rsync commands
        we exec to stdout.
    Raises:
      BadConfigurationException: If local_appscale_dir does not exist locally,
        or if any of the standard AppScale module folders do not exist.
    """
    ssh_key = LocalState.get_key_path_from_name(keyname)
    appscale_dirs = ["lib", "AppController", "AppManager", "AppServer",
      "AppLoadBalancer", "AppMonitoring", "Neptune", "InfrastructureManager"]
    for dir_name in appscale_dirs:
      local_path = os.path.expanduser(local_appscale_dir) + os.sep + dir_name
      if not os.path.exists(local_path):
        raise BadConfigurationException("The location you specified to copy " +
          "from, {0}, doesn't contain a {1} folder.".format(local_appscale_dir,
          local_path))
      LocalState.shell("rsync -e 'ssh -i {0} {1}' -arv {2}/* root@{3}:/root/appscale/{4}" \
        .format(ssh_key, cls.SSH_OPTIONS, local_path, host, dir_name), is_verbose)

    # Rsync AppDB separately, as it has a lot of paths we may need to exclude
    # (e.g., built database binaries).
    local_app_db = os.path.expanduser(local_appscale_dir) + os.sep + "AppDB/*"
    LocalState.shell("rsync -e 'ssh -i {0} {1}' -arv --exclude='logs/*' --exclude='hadoop-*' --exclude='hbase/hbase-*' --exclude='voldemort/voldemort/*' --exclude='cassandra/cassandra/*' {2} root@{3}:/root/appscale/AppDB".format(ssh_key, cls.SSH_OPTIONS, local_app_db, host), is_verbose)
Пример #2
0
    def scp_remote_to_local(cls,
                            host,
                            keyname,
                            source,
                            dest,
                            is_verbose,
                            user='******'):
        """Securely copies a file from a remote machine to this machine.

    Args:
      host: A str representing the machine that we should log into.
      keyname: A str representing the name of the SSH keypair to log in with.
      source: A str representing the path on the remote machine where the
        file should be copied from.
      dest: A str representing the path on the local machine where the file
        should be copied to.
      is_verbose: A bool that indicates if we should print the scp command to
        stdout.
      user: A str representing the user to log in as.
    Returns:
      A str representing the standard output of the secure copy and a str
        representing the standard error of the secure copy.
    """
        ssh_key = LocalState.get_key_path_from_name(keyname)
        return LocalState.shell(
            "scp -r -i {0} {1} {2}@{3}:{4} {5}".format(ssh_key,
                                                       cls.SSH_OPTIONS, user,
                                                       host, source, dest),
            is_verbose)
Пример #3
0
    def rsync_files(cls, host, keyname, local_appscale_dir, is_verbose):
        """Copies over an AppScale source directory from this machine to the
    specified host.

    Args:
      host: A str representing a host that should be accessible from this
        machine.
      keyname: A str representing the name of the SSH keypair that can log into
        the specified machine.
      local_appscale_dir: A str representing the path on the local filesystem
        where the AppScale source to copy over can be found.
      is_verbose: A bool that indicates if we should print the rsync commands
        we exec to stdout.
    Raises:
      BadConfigurationException: If local_appscale_dir does not exist locally,
        or if any of the standard AppScale module folders do not exist.
    """
        ssh_key = LocalState.get_key_path_from_name(keyname)
        local_path = os.path.expanduser(local_appscale_dir)
        if not os.path.exists(local_path):
            raise BadConfigurationException("The location you specified to copy " \
              "from, {0}, doesn't exist.".format(local_path))
        LocalState.shell("rsync -e 'ssh -i {0} {1}' -arv "
          "--exclude='AppDB/logs/*' " \
          "--exclude='AppDB/cassandra/cassandra/*' " \
          "{2}/* root@{3}:/root/appscale/".format(ssh_key, cls.SSH_OPTIONS,
          local_path, host), is_verbose)
Пример #4
0
    def copy_deployment_credentials(cls, host, options):
        """Copies credentials needed to start the AppController and have it create
    other instances (in cloud deployments).

    Args:
      host: A str representing the machine (reachable from this computer) to
        copy our deployment credentials to.
      options: A Namespace that indicates which SSH keypair to use, and whether
        or not we are running in a cloud infrastructure.
    """
        cls.scp(host, options.keyname,
                LocalState.get_secret_key_location(options.keyname),
                '/etc/appscale/secret.key', options.verbose)
        cls.scp(host, options.keyname,
                LocalState.get_key_path_from_name(options.keyname),
                '/etc/appscale/ssh.key', options.verbose)

        LocalState.generate_ssl_cert(options.keyname, options.verbose)
        cls.scp(host, options.keyname,
                LocalState.get_certificate_location(options.keyname),
                '/etc/appscale/certs/mycert.pem', options.verbose)
        cls.scp(host, options.keyname,
                LocalState.get_private_key_location(options.keyname),
                '/etc/appscale/certs/mykey.pem', options.verbose)

        hash_id = subprocess.Popen([
            "openssl", "x509", "-hash", "-noout", "-in",
            LocalState.get_certificate_location(options.keyname)
        ],
                                   stdout=subprocess.PIPE).communicate()[0]
        cls.ssh(host, options.keyname,
          'ln -fs /etc/appscale/certs/mycert.pem /etc/ssl/certs/{0}.0'.\
            format(hash_id.rstrip()),
          options.verbose)

        AppScaleLogger.log("Copying over deployment credentials")
        cert = LocalState.get_certificate_location(options.keyname)
        private_key = LocalState.get_private_key_location(options.keyname)

        cls.ssh(host, options.keyname, 'mkdir -p /etc/appscale/keys/cloud1',
                options.verbose)
        cls.scp(host, options.keyname, cert,
                "/etc/appscale/keys/cloud1/mycert.pem", options.verbose)
        cls.scp(host, options.keyname, private_key,
                "/etc/appscale/keys/cloud1/mykey.pem", options.verbose)

        # In Google Compute Engine, we also need to copy over our client_secrets
        # file and the OAuth2 file that the user has approved for use with their
        # credentials, otherwise the AppScale VMs won't be able to interact with
        # GCE.
        if options.infrastructure and options.infrastructure == 'gce':
            if os.path.exists(LocalState.get_client_secrets_location( \
                options.keyname)):
                cls.scp(
                    host, options.keyname,
                    LocalState.get_client_secrets_location(options.keyname),
                    '/etc/appscale/client_secrets.json', options.verbose)
            cls.scp(host, options.keyname,
                    LocalState.get_oauth2_storage_location(options.keyname),
                    '/etc/appscale/oauth2.dat', options.verbose)
Пример #5
0
    def ssh(cls,
            host,
            keyname,
            command,
            is_verbose,
            user='******',
            num_retries=LocalState.DEFAULT_NUM_RETRIES):
        """Logs into the named host and executes the given command.

    Args:
      host: A str representing the machine that we should log into.
      keyname: A str representing the name of the SSH keypair to log in with.
      command: A str representing what to execute on the remote host.
      is_verbose: A bool indicating if we should print the ssh command to
        stdout.
      user: A str representing the user to log in as.
    Returns:
      A str representing the standard output of the remote command and a str
        representing the standard error of the remote command.
    """
        ssh_key = LocalState.get_key_path_from_name(keyname)
        return LocalState.shell(
            "ssh -F /dev/null -i {0} {1} {2}@{3} bash".format(
                ssh_key, cls.SSH_OPTIONS, user, host),
            is_verbose,
            num_retries,
            stdin=command)
Пример #6
0
  def rsync_files(cls, host, keyname, local_appscale_dir, is_verbose):
    """Copies over an AppScale source directory from this machine to the
    specified host.

    Args:
      host: A str representing a host that should be accessible from this
        machine.
      keyname: A str representing the name of the SSH keypair that can log into
        the specified machine.
      local_appscale_dir: A str representing the path on the local filesystem
        where the AppScale source to copy over can be found.
      is_verbose: A bool that indicates if we should print the rsync commands
        we exec to stdout.
    Raises:
      BadConfigurationException: If local_appscale_dir does not exist locally,
        or if any of the standard AppScale module folders do not exist.
    """
    ssh_key = LocalState.get_key_path_from_name(keyname)
    local_path = os.path.expanduser(local_appscale_dir)
    if not os.path.exists(local_path):
      raise BadConfigurationException("The location you specified to copy " \
        "from, {0}, doesn't exist.".format(local_path))
    LocalState.shell("rsync -e 'ssh -i {0} {1}' -arv "
      "--exclude='AppDB/logs/*' " \
      "--exclude='AppDB/cassandra/cassandra/*' " \
      "{2}/* root@{3}:/root/appscale/".format(ssh_key, cls.SSH_OPTIONS,
      local_path, host), is_verbose)
Пример #7
0
  def copy_deployment_credentials(cls, host, options):
    """Copies credentials needed to start the AppController and have it create
    other instances (in cloud deployments).

    Args:
      host: A str representing the machine (reachable from this computer) to
        copy our deployment credentials to.
      options: A Namespace that indicates which SSH keypair to use, and whether
        or not we are running in a cloud infrastructure.
    """
    cls.scp(host, options.keyname, LocalState.get_secret_key_location(
      options.keyname), '/etc/appscale/secret.key', options.verbose)
    cls.scp(host, options.keyname, LocalState.get_key_path_from_name(
      options.keyname), '/etc/appscale/ssh.key', options.verbose)

    LocalState.generate_ssl_cert(options.keyname, options.verbose)
    cls.scp(host, options.keyname, LocalState.get_certificate_location(
      options.keyname), '/etc/appscale/certs/mycert.pem', options.verbose)
    cls.scp(host, options.keyname, LocalState.get_private_key_location(
      options.keyname), '/etc/appscale/certs/mykey.pem', options.verbose)

    AppScaleLogger.log("Copying over deployment credentials")
    cert = LocalState.get_certificate_location(options.keyname)
    private_key = LocalState.get_private_key_location(options.keyname)

    cls.ssh(host, options.keyname, 'mkdir -p /etc/appscale/keys/cloud1',
      options.verbose)
    cls.scp(host, options.keyname, cert, "/etc/appscale/keys/cloud1/mycert.pem",
      options.verbose)
    cls.scp(host, options.keyname, private_key,
      "/etc/appscale/keys/cloud1/mykey.pem", options.verbose)
Пример #8
0
    def copy_deployment_credentials(cls, host, options):
        """Copies credentials needed to start the AppController and have it create
    other instances (in cloud deployments).

    Args:
      host: A str representing the machine (reachable from this computer) to
        copy our deployment credentials to.
      options: A Namespace that indicates which SSH keypair to use, and whether
        or not we are running in a cloud infrastructure.
    """
        local_secret_key = LocalState.get_secret_key_location(options.keyname)
        cls.scp(host, options.keyname, local_secret_key,
                '{}/secret.key'.format(cls.CONFIG_DIR), options.verbose)

        local_ssh_key = LocalState.get_key_path_from_name(options.keyname)
        cls.scp(host, options.keyname, local_ssh_key,
                '{}/ssh.key'.format(cls.CONFIG_DIR), options.verbose)

        LocalState.generate_ssl_cert(options.keyname, options.verbose)

        local_cert = LocalState.get_certificate_location(options.keyname)
        cls.scp(host, options.keyname, local_cert,
                '{}/certs/mycert.pem'.format(cls.CONFIG_DIR), options.verbose)

        local_private_key = LocalState.get_private_key_location(
            options.keyname)
        cls.scp(host, options.keyname, local_private_key,
                '{}/certs/mykey.pem'.format(cls.CONFIG_DIR), options.verbose)

        hash_id = subprocess.Popen([
            "openssl", "x509", "-hash", "-noout", "-in",
            LocalState.get_certificate_location(options.keyname)
        ],
                                   stdout=subprocess.PIPE).communicate()[0]
        symlink_cert = 'ln -fs {}/certs/mycert.pem /etc/ssl/certs/{}.0'.\
          format(cls.CONFIG_DIR, hash_id.rstrip())
        cls.ssh(host, options.keyname, symlink_cert, options.verbose)

        # In Google Compute Engine, we also need to copy over our client_secrets
        # file and the OAuth2 file that the user has approved for use with their
        # credentials, otherwise the AppScale VMs won't be able to interact with
        # GCE.
        if options.infrastructure and options.infrastructure == 'gce':
            secrets_location = LocalState.get_client_secrets_location(
                options.keyname)
            if not os.path.exists(secrets_location):
                raise AppScaleException(
                    '{} does not exist.'.format(secrets_location))
            secrets_type = GCEAgent.get_secrets_type(secrets_location)
            cls.scp(host, options.keyname, secrets_location,
                    '{}/client_secrets.json'.format(cls.CONFIG_DIR),
                    options.verbose)
            if secrets_type == CredentialTypes.OAUTH:
                local_oauth = LocalState.get_oauth2_storage_location(
                    options.keyname)
                cls.scp(host, options.keyname, local_oauth,
                        '{}/oauth2.dat'.format(cls.CONFIG_DIR),
                        options.verbose)
Пример #9
0
  def get_command_output_from_remote(cls, host, command, keyname, user='******',
                                     shell=False):
    """ Get the file from the location in the remote and passes the contents.

    Args:
      host: A str representing the machine that we should log into.
      command: A str representing the command to run on the remote machine.
      user: A str representing the user to log in as.
    """
    user_login = user + '@' + host
    key_path = LocalState.get_key_path_from_name(keyname)
    return subprocess.Popen(['ssh', '-i', key_path, user_login, command], shell, stdout=subprocess.PIPE)
Пример #10
0
  def test_get_key_path_from_local_appscale(self):
    keyname = "keyname"
    # Test key path returned is ~/.appscale when .key file is present in
    # that location.
    local_appscale_key_file_path = LocalState.LOCAL_APPSCALE_PATH + keyname + \
      ".key"
    os.path.should_receive('isfile').with_args(local_appscale_key_file_path). \
      and_return(True)
    actual_key_path = LocalState.get_key_path_from_name(keyname)
    self.assertEquals(local_appscale_key_file_path, actual_key_path)

    # Test key path returned is /etc/appscale/keys/cloud1/when .key file is
    # present in that location.
    etc_appscale_key_file_path = LocalState.ETC_APPSCALE_KEY_PATH + keyname + \
      ".key"
    os.path.should_receive('isfile').with_args(local_appscale_key_file_path). \
      and_return(False)
    os.path.should_receive('isfile').with_args(etc_appscale_key_file_path). \
      and_return(True)
    actual_key_path = LocalState.get_key_path_from_name(keyname)
    self.assertEquals(etc_appscale_key_file_path, actual_key_path)
Пример #11
0
    def test_get_key_path_from_local_appscale(self):
        keyname = "keyname"
        # Test key path returned is ~/.appscale when .key file is present in
        # that location.
        local_appscale_key_file_path = LocalState.LOCAL_APPSCALE_PATH + keyname + \
          ".key"
        os.path.should_receive('isfile').with_args(local_appscale_key_file_path). \
          and_return(True)
        actual_key_path = LocalState.get_key_path_from_name(keyname)
        self.assertEquals(local_appscale_key_file_path, actual_key_path)

        # Test key path returned is /etc/appscale/keys/cloud1/when .key file is
        # present in that location.
        etc_appscale_key_file_path = LocalState.ETC_APPSCALE_KEY_PATH + keyname + \
          ".key"
        os.path.should_receive('isfile').with_args(local_appscale_key_file_path). \
          and_return(False)
        os.path.should_receive('isfile').with_args(etc_appscale_key_file_path). \
          and_return(True)
        actual_key_path = LocalState.get_key_path_from_name(keyname)
        self.assertEquals(etc_appscale_key_file_path, actual_key_path)
Пример #12
0
  def copy_deployment_credentials(cls, host, options):
    """Copies credentials needed to start the AppController and have it create
    other instances (in cloud deployments).

    Args:
      host: A str representing the machine (reachable from this computer) to
        copy our deployment credentials to.
      options: A Namespace that indicates which SSH keypair to use, and whether
        or not we are running in a cloud infrastructure.
    """
    cls.scp(host, options.keyname, LocalState.get_secret_key_location(
      options.keyname), '/etc/appscale/secret.key', options.verbose)
    cls.scp(host, options.keyname, LocalState.get_key_path_from_name(
      options.keyname), '/etc/appscale/ssh.key', options.verbose)

    LocalState.generate_ssl_cert(options.keyname, options.verbose)
    cls.scp(host, options.keyname, LocalState.get_certificate_location(
      options.keyname), '/etc/appscale/certs/mycert.pem', options.verbose)
    cls.scp(host, options.keyname, LocalState.get_private_key_location(
      options.keyname), '/etc/appscale/certs/mykey.pem', options.verbose)

    hash_id = subprocess.Popen(["openssl", "x509", "-hash", "-noout", "-in",
      LocalState.get_certificate_location(options.keyname)],
      stdout=subprocess.PIPE).communicate()[0]
    cls.ssh(host, options.keyname,
      'ln -fs /etc/appscale/certs/mycert.pem /etc/ssl/certs/{0}.0'.\
        format(hash_id.rstrip()),
      options.verbose)

    AppScaleLogger.log("Copying over deployment credentials")
    cert = LocalState.get_certificate_location(options.keyname)
    private_key = LocalState.get_private_key_location(options.keyname)

    cls.ssh(host, options.keyname, 'mkdir -p /etc/appscale/keys/cloud1',
      options.verbose)
    cls.scp(host, options.keyname, cert, "/etc/appscale/keys/cloud1/mycert.pem",
      options.verbose)
    cls.scp(host, options.keyname, private_key,
      "/etc/appscale/keys/cloud1/mykey.pem", options.verbose)

    # In Google Compute Engine, we also need to copy over our client_secrets
    # file and the OAuth2 file that the user has approved for use with their
    # credentials, otherwise the AppScale VMs won't be able to interact with
    # GCE.
    if options.infrastructure and options.infrastructure == 'gce':
      if os.path.exists(LocalState.get_client_secrets_location( \
          options.keyname)):
        cls.scp(host, options.keyname, LocalState.get_client_secrets_location(
          options.keyname), '/etc/appscale/client_secrets.json',
          options.verbose)
      cls.scp(host, options.keyname, LocalState.get_oauth2_storage_location(
        options.keyname), '/etc/appscale/oauth2.dat', options.verbose)
Пример #13
0
  def copy_deployment_credentials(cls, host, options):
    """Copies credentials needed to start the AppController and have it create
    other instances (in cloud deployments).

    Args:
      host: A str representing the machine (reachable from this computer) to
        copy our deployment credentials to.
      options: A Namespace that indicates which SSH keypair to use, and whether
        or not we are running in a cloud infrastructure.
    """
    local_secret_key = LocalState.get_secret_key_location(options.keyname)
    cls.scp(host, options.keyname, local_secret_key,
      '{}/secret.key'.format(cls.CONFIG_DIR), options.verbose)

    local_ssh_key = LocalState.get_key_path_from_name(options.keyname)
    cls.scp(host, options.keyname, local_ssh_key,
      '{}/ssh.key'.format(cls.CONFIG_DIR), options.verbose)

    LocalState.generate_ssl_cert(options.keyname, options.verbose)

    local_cert = LocalState.get_certificate_location(options.keyname)
    cls.scp(host, options.keyname, local_cert,
      '{}/certs/mycert.pem'.format(cls.CONFIG_DIR), options.verbose)

    local_private_key = LocalState.get_private_key_location(options.keyname)
    cls.scp(host, options.keyname, local_private_key,
      '{}/certs/mykey.pem'.format(cls.CONFIG_DIR), options.verbose)

    hash_id = subprocess.Popen(["openssl", "x509", "-hash", "-noout", "-in",
      LocalState.get_certificate_location(options.keyname)],
      stdout=subprocess.PIPE).communicate()[0]
    symlink_cert = 'ln -fs {}/certs/mycert.pem /etc/ssl/certs/{}.0'.\
      format(cls.CONFIG_DIR, hash_id.rstrip())
    cls.ssh(host, options.keyname, symlink_cert, options.verbose)

    # In Google Compute Engine, we also need to copy over our client_secrets
    # file and the OAuth2 file that the user has approved for use with their
    # credentials, otherwise the AppScale VMs won't be able to interact with
    # GCE.
    if options.infrastructure and options.infrastructure == 'gce':
      secrets_location = LocalState.get_client_secrets_location(options.keyname)
      if not os.path.exists(secrets_location):
        raise AppScaleException('{} does not exist.'.format(secrets_location))
      secrets_type = GCEAgent.get_secrets_type(secrets_location)
      cls.scp(host, options.keyname, secrets_location,
        '{}/client_secrets.json'.format(cls.CONFIG_DIR), options.verbose)
      if secrets_type == CredentialTypes.OAUTH:
        local_oauth = LocalState.get_oauth2_storage_location(options.keyname)
        cls.scp(host, options.keyname, local_oauth,
          '{}/oauth2.dat'.format(cls.CONFIG_DIR), options.verbose)
Пример #14
0
    def rsync_files(cls, host, keyname, local_appscale_dir, is_verbose):
        """Copies over an AppScale source directory from this machine to the
    specified host.

    Args:
      host: A str representing a host that should be accessible from this
        machine.
      keyname: A str representing the name of the SSH keypair that can log into
        the specified machine.
      local_appscale_dir: A str representing the path on the local filesystem
        where the AppScale source to copy over can be found.
      is_verbose: A bool that indicates if we should print the rsync commands
        we exec to stdout.
    Raises:
      BadConfigurationException: If local_appscale_dir does not exist locally,
        or if any of the standard AppScale module folders do not exist.
    """
        ssh_key = LocalState.get_key_path_from_name(keyname)
        appscale_dirs = [
            "lib", "AppController", "AppManager", "AppServer",
            "AppServer_Java", "AppDashboard", "InfrastructureManager",
            "AppTaskQueue", "XMPPReceiver"
        ]
        for dir_name in appscale_dirs:
            local_path = os.path.expanduser(
                local_appscale_dir) + os.sep + dir_name
            if not os.path.exists(local_path):
                raise BadConfigurationException("The location you specified to copy " \
                  "from, {0}, doesn't contain a {1} folder.".format(local_appscale_dir,
                  local_path))
            LocalState.shell("rsync -e 'ssh -i {0} {1}' -arv {2}/* "\
              "root@{3}:/root/appscale/{4}".format(ssh_key, cls.SSH_OPTIONS,
              local_path, host, dir_name), is_verbose)

        # Rsync AppDB separately, as it has a lot of paths we may need to exclude
        # (e.g., built database binaries).
        local_app_db = os.path.expanduser(
            local_appscale_dir) + os.sep + "AppDB/*"
        LocalState.shell("rsync -e 'ssh -i {0} {1}' -arv --exclude='logs/*' " \
          "--exclude='hadoop-*' --exclude='hbase/hbase-*' " \
          "--exclude='cassandra/cassandra/*' {2} root@{3}:/root/appscale/AppDB" \
          .format(ssh_key, cls.SSH_OPTIONS, local_app_db, host), is_verbose)

        # And rsync the firewall configuration file separately, as it's not a
        # directory (which the above all are).
        local_firewall = os.path.expanduser(local_appscale_dir) + os.sep + \
          "firewall.conf"
        LocalState.shell("rsync -e 'ssh -i {0} {1}' -arv {2} root@{3}:" \
          "/root/appscale/firewall.conf".format(ssh_key, cls.SSH_OPTIONS,
          local_firewall, host), is_verbose)
Пример #15
0
    def copy_ssh_keys_to_node(cls, host, keyname, is_verbose):
        """Sets the given SSH keypair as the default key for the named host,
    enabling it to log into other machines in the AppScale deployment without
    being prompted for a password or explicitly requiring the key to be
    provided.

    Args:
      host: A str representing the machine that we should log into.
      keyname: A str representing the name of the SSH keypair to log in with.
      is_verbose: A bool that indicates if we should print the SCP commands
        needed to copy the SSH keys over to stdout.
    """
        ssh_key = LocalState.get_key_path_from_name(keyname)
        cls.scp(host, keyname, ssh_key, "/root/.ssh/id_dsa", is_verbose)
        cls.scp(host, keyname, ssh_key, "/root/.ssh/id_rsa", is_verbose)
        cls.scp(host, keyname, ssh_key, "/root/.appscale/{0}.key".format(keyname), is_verbose)
Пример #16
0
  def copy_ssh_keys_to_node(cls, host, keyname, is_verbose):
    """Sets the given SSH keypair as the default key for the named host,
    enabling it to log into other machines in the AppScale deployment without
    being prompted for a password or explicitly requiring the key to be
    provided.

    Args:
      host: A str representing the machine that we should log into.
      keyname: A str representing the name of the SSH keypair to log in with.
      is_verbose: A bool that indicates if we should print the SCP commands
        needed to copy the SSH keys over to stdout.
    """
    ssh_key = LocalState.get_key_path_from_name(keyname)
    cls.scp(host, keyname, ssh_key, '/root/.ssh/id_dsa', is_verbose)
    cls.scp(host, keyname, ssh_key, '/root/.ssh/id_rsa', is_verbose)
    cls.scp(host, keyname, ssh_key, '/root/.appscale/{0}.key'.format(keyname),
      is_verbose)
Пример #17
0
  def ssh(cls, host, keyname, command, is_verbose, user='******'):
    """Logs into the named host and executes the given command.

    Args:
      host: A str representing the machine that we should log into.
      keyname: A str representing the name of the SSH keypair to log in with.
      command: A str representing what to execute on the remote host.
      is_verbose: A bool indicating if we should print the ssh command to
        stdout.
      user: A str representing the user to log in as.
    Returns:
      A str representing the standard output of the remote command and a str
        representing the standard error of the remote command.
    """
    ssh_key = LocalState.get_key_path_from_name(keyname)
    return LocalState.shell("ssh -i {0} {1} {2}@{3} '{4}'".format(ssh_key,
      cls.SSH_OPTIONS, user, host, command), is_verbose)
Пример #18
0
    def get_command_output_from_remote(cls,
                                       host,
                                       command,
                                       keyname,
                                       user='******',
                                       shell=False):
        """ Get the file from the location in the remote and passes the contents.

    Args:
      host: A str representing the machine that we should log into.
      command: A str representing the command to run on the remote machine.
      user: A str representing the user to log in as.
    """
        user_login = user + '@' + host
        key_path = LocalState.get_key_path_from_name(keyname)
        return subprocess.Popen(['ssh', '-i', key_path, user_login, command],
                                shell,
                                stdout=subprocess.PIPE)
Пример #19
0
  def scp(cls, host, keyname, source, dest, is_verbose, user='******'):
    """Securely copies a file from this machine to the named machine.

    Args:
      host: A str representing the machine that we should log into.
      keyname: A str representing the name of the SSH keypair to log in with.
      source: A str representing the path on the local machine where the
        file should be copied from.
      dest: A str representing the path on the remote machine where the file
        should be copied to.
      is_verbose: A bool that indicates if we should print the scp command to
        stdout.
      user: A str representing the user to log in as.
    Returns:
      A str representing the standard output of the secure copy and a str
        representing the standard error of the secure copy.
    """
    ssh_key = LocalState.get_key_path_from_name(keyname)
    return LocalState.shell("scp -i {0} {1} {2} {3}@{4}:{5}".format(ssh_key,
      cls.SSH_OPTIONS, source, user, host, dest), is_verbose)
Пример #20
0
  def start_head_node(cls, options, my_id, node_layout):
    """Starts the first node in an AppScale deployment and instructs it to start
    API services on its own node, as well as the other nodes in the deployment.

    This includes spawning the first node in the deployment, copying over all
    deployment-specific files to it, and starting its AppController service.

    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).
      my_id: A str that is used to uniquely identify this AppScale deployment
        with the remote start application.
      node_layout: A NodeLayout that describes the placement strategy that
        should be used for this AppScale deployment.
    Returns:
      The public IP and instance ID (a dummy value in non-cloud deployments)
      corresponding to the node that was started.
    Raises:
      AppControllerException: If the AppController on the head node crashes.
        The message in this exception indicates why the crash occurred.
    """
    secret_key = LocalState.generate_secret_key(options.keyname)
    AppScaleLogger.verbose("Secret key is {0}".format(secret_key),
      options.verbose)

    if options.infrastructure:
      instance_id, public_ip, private_ip = cls.spawn_node_in_cloud(options)
    else:
      instance_id = cls.DUMMY_INSTANCE_ID
      public_ip = node_layout.head_node().public_ip
      private_ip = node_layout.head_node().private_ip

    AppScaleLogger.log("Log in to your head node: ssh -i {0} root@{1}".format(
      LocalState.get_key_path_from_name(options.keyname), public_ip))

    try:
      cls.ensure_machine_is_compatible(public_ip, options.keyname,
        options.table, options.verbose)
    except AppScaleException as ase:
      # On failure shutdown the cloud instances, cleanup the keys, but only
      # if --test is not set.
      if options.infrastructure:
        if not options.test:
          try:
            cls.terminate_cloud_instance(instance_id, options)
          except Exception as tcie:
            AppScaleLogger.log("Error terminating instances: {0}"
              .format(str(tcie)))
        raise AppScaleException("{0} Please ensure that the "\
          "image {1} has AppScale {2} installed on it."
          .format(str(ase), options.machine, APPSCALE_VERSION))
      else:
        raise AppScaleException("{0} Please login to that machine and ensure "\
          "that AppScale {1} is installed on it."
          .format(str(ase), APPSCALE_VERSION))

    if options.scp:
      AppScaleLogger.log("Copying over local copy of AppScale from {0}".format(
        options.scp))
      cls.rsync_files(public_ip, options.keyname, options.scp, options.verbose)

    # On Euca, we've seen issues where attaching the EBS volume right after
    # the instance starts doesn't work. This sleep lets the instance fully
    # start up and get volumes attached to it correctly.
    if options.infrastructure and options.infrastructure == 'euca' and \
      options.disks:
      time.sleep(30)

    if options.infrastructure:
      agent = InfrastructureAgentFactory.create_agent(options.infrastructure)
      params = agent.get_params_from_args(options)
      additional_params = {}

      if agent.PARAM_CREDENTIALS in params:
        additional_params = params[agent.PARAM_CREDENTIALS]

      if options.use_spot_instances:
        additional_params[agent.PARAM_SPOT_PRICE] = \
          str(params[agent.PARAM_SPOT_PRICE])

      if agent.PARAM_REGION in params:
        additional_params[agent.PARAM_REGION] = params[agent.PARAM_REGION]
    else:
      additional_params = {}

    deployment_params = LocalState.generate_deployment_params(options,
      node_layout, public_ip, additional_params)
    AppScaleLogger.verbose(str(LocalState.obscure_dict(deployment_params)),
      options.verbose)
    AppScaleLogger.log("Head node successfully initialized at {0}.".format(public_ip))

    AppScaleLogger.remote_log_tools_state(options, my_id, "started head node",
      APPSCALE_VERSION)
    time.sleep(10)  # gives machines in cloud extra time to boot up

    cls.copy_deployment_credentials(public_ip, options)
    cls.run_user_commands(public_ip, options.user_commands, options.keyname,
      options.verbose)
    cls.start_remote_appcontroller(public_ip, options.keyname, options.verbose)

    acc = AppControllerClient(public_ip, secret_key)
    locations = [{
      'public_ip' : public_ip,
      'private_ip' : private_ip,
      'jobs' : node_layout.head_node().roles,
      'instance_id' : instance_id,
      'disk' : node_layout.head_node().disk
    }]
    try:
      acc.set_parameters(locations, LocalState.map_to_array(deployment_params))
    except Exception as exception:
      AppScaleLogger.warn('Saw Exception while setting AC parameters: {0}' \
        .format(str(exception)))
      message = RemoteHelper.collect_appcontroller_crashlog(public_ip,
        options.keyname, options.verbose)
      raise AppControllerException(message)

    return public_ip, instance_id
Пример #21
0
    def start_head_node(cls, options, my_id, node_layout):
        """Starts the first node in an AppScale deployment and instructs it to start
    API services on its own node, as well as the other nodes in the deployment.

    This includes spawning the first node in the deployment, copying over all
    deployment-specific files to it, and starting its AppController service.

    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).
      my_id: A str that is used to uniquely identify this AppScale deployment
        with the remote start application.
      node_layout: A NodeLayout that describes the placement strategy that
        should be used for this AppScale deployment.
    Returns:
      The public IP and instance ID (a dummy value in non-cloud deployments)
      corresponding to the node that was started.
    Raises:
      AppControllerException: If the AppController on the head node crashes.
        The message in this exception indicates why the crash occurred.
    """
        secret_key = LocalState.generate_secret_key(options.keyname)
        AppScaleLogger.verbose("Secret key is {0}".format(secret_key),
                               options.verbose)
        head_node = node_layout.head_node().public_ip

        AppScaleLogger.log(
            "Log in to your head node: ssh -i {0} root@{1}".format(
                LocalState.get_key_path_from_name(options.keyname), head_node))

        additional_params = {}
        if options.infrastructure:
            agent = InfrastructureAgentFactory.create_agent(
                options.infrastructure)
            params = agent.get_params_from_args(options)
            additional_params = {}

            if agent.PARAM_CREDENTIALS in params:
                additional_params = params[agent.PARAM_CREDENTIALS]

            if options.use_spot_instances:
                additional_params[agent.PARAM_SPOT_PRICE] = \
                  str(params[agent.PARAM_SPOT_PRICE])

            if agent.PARAM_REGION in params:
                additional_params[agent.PARAM_REGION] = params[
                    agent.PARAM_REGION]

        time.sleep(10)  # gives machines in cloud extra time to boot up

        cls.copy_deployment_credentials(head_node, options)

        cls.run_user_commands(head_node, options.user_commands,
                              options.keyname, options.verbose)

        cls.start_remote_appcontroller(head_node, options.keyname,
                                       options.verbose)
        AppScaleLogger.log(
            "Head node successfully initialized at {0}.".format(head_node))
        AppScaleLogger.remote_log_tools_state(options, my_id,
                                              "started head node",
                                              APPSCALE_VERSION)

        # Construct serverside compatible parameters.
        deployment_params = LocalState.generate_deployment_params(
            options, node_layout, additional_params)
        AppScaleLogger.verbose(str(LocalState.obscure_dict(deployment_params)),
                               options.verbose)

        acc = AppControllerClient(head_node, secret_key)
        try:
            acc.set_parameters(node_layout.to_list(), deployment_params)
        except Exception as exception:
            AppScaleLogger.warn(
                'Saw Exception while setting AC parameters: {0}'.format(
                    str(exception)))
            message = RemoteHelper.collect_appcontroller_crashlog(
                head_node, options.keyname, options.verbose)
            raise AppControllerException(message)
Пример #22
0
  def start_head_node(cls, options, node_layout):
    """Starts the first node in an AppScale deployment and instructs it to start
    API services on its own node, as well as the other nodes in the deployment.

    This includes spawning the first node in the deployment, copying over all
    deployment-specific files to it, and starting its AppController service.

    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: A NodeLayout that describes the placement strategy that
        should be used for this AppScale deployment.
    Returns:
      The public IP and instance ID (a dummy value in non-cloud deployments)
      corresponding to the node that was started.
    """
    secret_key = LocalState.generate_secret_key(options.keyname)
    AppScaleLogger.verbose("Secret key is {0}".format(secret_key),
      options.verbose)

    if options.infrastructure:
      instance_id, public_ip, private_ip = cls.spawn_node_in_cloud(options)
    else:
      instance_id = cls.DUMMY_INSTANCE_ID
      public_ip = node_layout.head_node().id
      private_ip = node_layout.head_node().id

    AppScaleLogger.log("Log in to your head node: ssh -i {0} root@{1}".format(
      LocalState.get_key_path_from_name(options.keyname), public_ip))

    cls.ensure_machine_is_compatible(public_ip, options.keyname, options.table,
      options.verbose)
    if options.scp:
      AppScaleLogger.log("Copying over local copy of AppScale from {0}".format(
        options.scp))
      cls.rsync_files(public_ip, options.keyname, options.scp, options.verbose)

    if options.infrastructure:
      agent = InfrastructureAgentFactory.create_agent(options.infrastructure)
      params = agent.get_params_from_args(options)
      additional_params = params[agent.PARAM_CREDENTIALS]
    else:
      additional_params = {}

    deployment_params = LocalState.generate_deployment_params(options,
      node_layout, public_ip, additional_params)
    AppScaleLogger.verbose(str(LocalState.obscure_dict(deployment_params)),
      options.verbose)
    AppScaleLogger.log("Head node successfully initialized at {0}. It is now starting up {1}.".format(public_ip, options.table))

    AppScaleLogger.remote_log_tools_state(options, "started head node")
    time.sleep(10)  # gives machines in cloud extra time to boot up

    cls.copy_deployment_credentials(public_ip, options)
    cls.start_remote_appcontroller(public_ip, options.keyname, options.verbose)

    acc = AppControllerClient(public_ip, secret_key)
    locations = ["{0}:{1}:{2}:{3}:cloud1".format(public_ip, private_ip,
      ":".join(node_layout.head_node().roles), instance_id)]
    acc.set_parameters(locations, LocalState.map_to_array(deployment_params))

    return public_ip, instance_id
Пример #23
0
    def start_head_node(cls, options, my_id, node_layout):
        """Starts the first node in an AppScale deployment and instructs it to start
    API services on its own node, as well as the other nodes in the deployment.

    This includes spawning the first node in the deployment, copying over all
    deployment-specific files to it, and starting its AppController service.

    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).
      my_id: A str that is used to uniquely identify this AppScale deployment
        with the remote start application.
      node_layout: A NodeLayout that describes the placement strategy that
        should be used for this AppScale deployment.
    Returns:
      The public IP and instance ID (a dummy value in non-cloud deployments)
      corresponding to the node that was started.
    Raises:
      AppControllerException: If the AppController on the head node crashes.
        The message in this exception indicates why the crash occurred.
    """
        secret_key = LocalState.generate_secret_key(options.keyname)
        AppScaleLogger.verbose("Secret key is {0}".format(secret_key),
                               options.verbose)

        if options.infrastructure:
            instance_id, public_ip, private_ip = cls.spawn_node_in_cloud(
                options)
        else:
            instance_id = cls.DUMMY_INSTANCE_ID
            public_ip = node_layout.head_node().public_ip
            private_ip = node_layout.head_node().private_ip

        AppScaleLogger.log(
            "Log in to your head node: ssh -i {0} root@{1}".format(
                LocalState.get_key_path_from_name(options.keyname), public_ip))

        try:
            cls.ensure_machine_is_compatible(public_ip, options.keyname,
                                             options.table, options.verbose)
        except AppScaleException as ase:
            # On failure shutdown the cloud instances, cleanup the keys, but only
            # if --test is not set.
            if options.infrastructure:
                if not options.test:
                    try:
                        cls.terminate_cloud_instance(instance_id, options)
                    except Exception as tcie:
                        AppScaleLogger.log(
                            "Error terminating instances: {0}".format(
                                str(tcie)))
                raise AppScaleException("{0} Please ensure that the "\
                  "image {1} has AppScale {2} installed on it."
                  .format(str(ase), options.machine, APPSCALE_VERSION))
            else:
                raise AppScaleException("{0} Please login to that machine and ensure "\
                  "that AppScale {1} is installed on it."
                  .format(str(ase), APPSCALE_VERSION))

        if options.scp:
            AppScaleLogger.log(
                "Copying over local copy of AppScale from {0}".format(
                    options.scp))
            cls.rsync_files(public_ip, options.keyname, options.scp,
                            options.verbose)

        # On Euca, we've seen issues where attaching the EBS volume right after
        # the instance starts doesn't work. This sleep lets the instance fully
        # start up and get volumes attached to it correctly.
        if options.infrastructure and options.infrastructure == 'euca' and \
          options.disks:
            time.sleep(30)

        if options.infrastructure:
            agent = InfrastructureAgentFactory.create_agent(
                options.infrastructure)
            params = agent.get_params_from_args(options)
            additional_params = {}

            if agent.PARAM_CREDENTIALS in params:
                additional_params = params[agent.PARAM_CREDENTIALS]

            if options.use_spot_instances:
                additional_params[agent.PARAM_SPOT_PRICE] = \
                  str(params[agent.PARAM_SPOT_PRICE])

            if agent.PARAM_REGION in params:
                additional_params[agent.PARAM_REGION] = params[
                    agent.PARAM_REGION]
        else:
            additional_params = {}

        deployment_params = LocalState.generate_deployment_params(
            options, node_layout, public_ip, additional_params)
        AppScaleLogger.verbose(str(LocalState.obscure_dict(deployment_params)),
                               options.verbose)
        AppScaleLogger.log(
            "Head node successfully initialized at {0}.".format(public_ip))

        AppScaleLogger.remote_log_tools_state(options, my_id,
                                              "started head node",
                                              APPSCALE_VERSION)
        time.sleep(10)  # gives machines in cloud extra time to boot up

        cls.copy_deployment_credentials(public_ip, options)
        cls.run_user_commands(public_ip, options.user_commands,
                              options.keyname, options.verbose)
        cls.start_remote_appcontroller(public_ip, options.keyname,
                                       options.verbose)

        acc = AppControllerClient(public_ip, secret_key)
        locations = [{
            'public_ip': public_ip,
            'private_ip': private_ip,
            'jobs': node_layout.head_node().roles,
            'instance_id': instance_id,
            'disk': node_layout.head_node().disk
        }]
        try:
            acc.set_parameters(locations,
                               LocalState.map_to_array(deployment_params))
        except Exception as exception:
            AppScaleLogger.warn('Saw Exception while setting AC parameters: {0}' \
              .format(str(exception)))
            message = RemoteHelper.collect_appcontroller_crashlog(
                public_ip, options.keyname, options.verbose)
            raise AppControllerException(message)

        return public_ip, instance_id
Пример #24
0
 def ssh(self, command):
   key_path = LocalState.get_key_path_from_name(self.key_name)
   ssh_command = "ssh -i {0} {1}@{2}  ".format(key_path, "root", self.service_host)
   p = subprocess.Popen(ssh_command + command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
   return p.stdout.read()
Пример #25
0
  def start_head_node(cls, options, my_id, node_layout):
    """Starts the first node in an AppScale deployment and instructs it to start
    API services on its own node, as well as the other nodes in the deployment.

    This includes spawning the first node in the deployment, copying over all
    deployment-specific files to it, and starting its AppController service.

    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).
      my_id: A str that is used to uniquely identify this AppScale deployment
        with the remote start application.
      node_layout: A NodeLayout that describes the placement strategy that
        should be used for this AppScale deployment.
    Returns:
      The public IP and instance ID (a dummy value in non-cloud deployments)
      corresponding to the node that was started.
    """
    secret_key = LocalState.generate_secret_key(options.keyname)
    AppScaleLogger.verbose("Secret key is {0}".format(secret_key),
      options.verbose)

    if options.infrastructure:
      instance_id, public_ip, private_ip = cls.spawn_node_in_cloud(options)
    else:
      instance_id = cls.DUMMY_INSTANCE_ID
      public_ip = node_layout.head_node().public_ip
      private_ip = node_layout.head_node().private_ip

    AppScaleLogger.log("Log in to your head node: ssh -i {0} root@{1}".format(
      LocalState.get_key_path_from_name(options.keyname), public_ip))

    try:
      cls.ensure_machine_is_compatible(public_ip, options.keyname,
        options.table, options.verbose)
    except AppScaleException as ase:
       # On failure shutdown the cloud instances, cleanup the keys, but only 
       # if --test is not set.
       if options.infrastructure:
         if not options.test:
           try:
             cls.terminate_cloud_instance(instance_id, options)
           except Exception as tcie:
             AppScaleLogger.log("Error terminating instances: {0}"
               .format(str(tcie)))
         raise AppScaleException("{0} Please ensure that the "\
           "image {1} has AppScale {2} installed on it."
           .format(str(ase),options.machine,APPSCALE_VERSION))
       else:
         raise AppScaleException("{0} Please login to that machine and ensure "\
           "that AppScale {1} is installed on it."
           .format(str(ase),APPSCALE_VERSION))

    if options.scp:
      AppScaleLogger.log("Copying over local copy of AppScale from {0}".format(
        options.scp))
      cls.rsync_files(public_ip, options.keyname, options.scp, options.verbose)

    if options.infrastructure:
      agent = InfrastructureAgentFactory.create_agent(options.infrastructure)
      params = agent.get_params_from_args(options)
      additional_params = params[agent.PARAM_CREDENTIALS]

      if options.use_spot_instances:
        additional_params[agent.PARAM_SPOT_PRICE] = str(params[agent.PARAM_SPOT_PRICE])
    else:
      additional_params = {}

    deployment_params = LocalState.generate_deployment_params(options,
      node_layout, public_ip, additional_params)
    AppScaleLogger.verbose(str(LocalState.obscure_dict(deployment_params)),
      options.verbose)
    AppScaleLogger.log("Head node successfully initialized at {0}. It is now "\
      "starting up {1}.".format(public_ip, options.table))

    AppScaleLogger.remote_log_tools_state(options, my_id, "started head node",
      APPSCALE_VERSION)
    time.sleep(10)  # gives machines in cloud extra time to boot up

    cls.copy_deployment_credentials(public_ip, options)
    cls.start_remote_appcontroller(public_ip, options.keyname, options.verbose)

    acc = AppControllerClient(public_ip, secret_key)
    locations = ["{0}:{1}:{2}:{3}:cloud1".format(public_ip, private_ip,
      ":".join(node_layout.head_node().roles), instance_id)]
    acc.set_parameters(locations, LocalState.map_to_array(deployment_params))

    return public_ip, instance_id
Пример #26
0
  def start_head_node(cls, options, my_id, node_layout):
    """Starts the first node in an AppScale deployment and instructs it to start
    API services on its own node, as well as the other nodes in the deployment.

    This includes spawning the first node in the deployment, copying over all
    deployment-specific files to it, and starting its AppController service.

    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).
      my_id: A str that is used to uniquely identify this AppScale deployment
        with the remote start application.
      node_layout: A NodeLayout that describes the placement strategy that
        should be used for this AppScale deployment.
    Returns:
      The public IP and instance ID (a dummy value in non-cloud deployments)
      corresponding to the node that was started.
    Raises:
      AppControllerException: If the AppController on the head node crashes.
        The message in this exception indicates why the crash occurred.
    """
    secret_key = LocalState.generate_secret_key(options.keyname)
    AppScaleLogger.verbose("Secret key is {0}".
                           format(secret_key), options.verbose)
    head_node = node_layout.head_node().public_ip

    AppScaleLogger.log("Log in to your head node: ssh -i {0} root@{1}".format(
      LocalState.get_key_path_from_name(options.keyname), head_node))

    additional_params = {}
    if options.infrastructure:
      agent = InfrastructureAgentFactory.create_agent(options.infrastructure)
      params = agent.get_params_from_args(options)
      additional_params = {}

      if agent.PARAM_CREDENTIALS in params:
        additional_params = params[agent.PARAM_CREDENTIALS]

      if options.use_spot_instances:
        additional_params[agent.PARAM_SPOT_PRICE] = \
          str(params[agent.PARAM_SPOT_PRICE])

      if agent.PARAM_REGION in params:
        additional_params[agent.PARAM_REGION] = params[agent.PARAM_REGION]

      time.sleep(10)  # gives machines in cloud extra time to boot up

    cls.copy_deployment_credentials(head_node, options)

    cls.run_user_commands(head_node, options.user_commands, options.keyname,
                          options.verbose)

    cls.start_remote_appcontroller(head_node, options.keyname, options.verbose)
    AppScaleLogger.log("Head node successfully initialized at {0}.".
                       format(head_node))
    AppScaleLogger.remote_log_tools_state(
      options, my_id, "started head node", APPSCALE_VERSION)

    # Construct serverside compatible parameters.
    deployment_params = LocalState.generate_deployment_params(
      options, node_layout, additional_params)
    AppScaleLogger.verbose(str(LocalState.obscure_dict(deployment_params)),
                           options.verbose)

    acc = AppControllerClient(head_node, secret_key)
    try:
      acc.set_parameters(node_layout.to_list(), deployment_params)
    except Exception as exception:
      AppScaleLogger.warn(u'Saw Exception while setting AC parameters: {0}'.
                          format(str(exception)))
      message = RemoteHelper.collect_appcontroller_crashlog(
        head_node, options.keyname, options.verbose)
      raise AppControllerException(message)