def stop_app_instance(app_name, port):
  """ Stops a Google App Engine application process instance on current 
      machine.

  Args:
    app_name: Name of application to stop
    port: The port the application is running on
  Returns:
    True on success, False otherwise
  """
  if not misc.is_app_name_valid(app_name): 
    logging.error("Unable to kill app process %s on port %d because of " +\
                  "invalid name for application"%(app_name, int(port)))
    return False

  logging.info("Stopping application %s"%app_name)
  watch = "app___" + app_name + "-" + str(port)
  god_result = god_interface.stop(watch)

  # hack: God fails to shutdown processes so we do it via a system command
  # TODO: fix it or find an alternative to god
  pid_file = constants.APP_PID_DIR + app_name + '-' + port
  pid = file_io.read(pid_file)

  if str(port).isdigit(): 
    if subprocess.call(['kill', '-9', pid]) != 0:
      logging.error("Unable to kill app process %s on port %d with pid %s"%\
                    (app_name, int(port), str(pid)))

  file_io.delete(pid_file)

  return god_result
def stop_app_instance(app_name, port):
  """ Stops a Google App Engine application process instance on current
      machine.

  Args:
    app_name: A string, the name of application to stop.
    port: The port the application is running on.
  Returns:
    True on success, False otherwise.
  """
  if not misc.is_app_name_valid(app_name):
    logging.error("Unable to kill app process %s on port %d because of " \
      "invalid name for application" % (app_name, int(port)))
    return False

  logging.info('Removing routing for {} on port {}'.format(app_name, port))
  remove_routing(app_name, port)

  logging.info("Stopping application %s" % app_name)
  watch = "app___" + app_name + "-" + str(port)
  if not monit_interface.stop(watch, is_group=False):
    logging.error("Unable to stop application server for app {0} on " \
      "port {1}".format(app_name, port))
    return False

  # Now that the AppServer is stopped, remove its monit config file so that
  # monit doesn't pick it up and restart it.
  monit_config_file = '{}/appscale-{}.cfg'.format(MONIT_CONFIG_DIR, watch)
  try:
    os.remove(monit_config_file)
  except OSError as os_error:
    logging.error("Error deleting {0}".format(monit_config_file))

  return True
def stop_app(app_name):
  """ Stops all process instances of a Google App Engine application on this
      machine.

  Args:
    app_name: Name of application to stop
  Returns:
    True on success, False otherwise
  """
  if not misc.is_app_name_valid(app_name):
    logging.error("Unable to kill app process %s on because of " \
      "invalid name for application" % (app_name))
    return False

  logging.info("Stopping application %s" % app_name)
  watch = "app___" + app_name
  monit_result = monit_interface.stop(watch)

  if not monit_result:
    logging.error("Unable to shut down monit interface for watch %s" % watch)
    return False

  # Remove the monit config files for the application.
  # TODO: Reload monit to pick up config changes.
  config_files = glob.glob('{}/appscale-{}-*.cfg'.format(MONIT_CONFIG_DIR, watch))
  for config_file in config_files:
    try:
      os.remove(config_file)
    except OSError:
      logging.exception('Error removing {}'.format(config_file))

  return True
def stop_app_instance(app_name, port):
  """ Stops a Google App Engine application process instance on current
      machine.

  Args:
    app_name: Name of application to stop
    port: The port the application is running on
  Returns:
    True on success, False otherwise
  """
  if not misc.is_app_name_valid(app_name):
    logging.error("Unable to kill app process %s on port %d because of " +\
                  "invalid name for application"%(app_name, int(port)))
    return False

  logging.info("Stopping application %s"%app_name)
  watch = "app___" + app_name + "-" + str(port)
  if not monit_interface.stop(watch, is_group=False):
    logging.error("Unable to stop application server for app {0} on " \
      "port {1}".format(app_name, port))
    return False

  # Now that the AppServer is stopped, remove its monit config file so that
  # monit doesn't pick it up and restart it.
  monit_config_file = "/etc/monit/conf.d/{0}.cfg".format(watch)
  os.remove(monit_config_file)
  return True
Exemple #5
0
 def test_is_app_name_valid(self):
   self.assertEqual(True, misc.is_app_name_valid("guestbook"))
   self.assertEqual(True, misc.is_app_name_valid("guestbook132"))
   self.assertEqual(True, misc.is_app_name_valid("guestbook_132"))
   self.assertEqual(True, misc.is_app_name_valid("guestbook-132"))
   self.assertEqual(False, misc.is_app_name_valid("asdf#"))
   self.assertEqual(False, misc.is_app_name_valid("%##;"))
   self.assertEqual(False, misc.is_app_name_valid("$78;"))
def restart_app_instances_for_app(app_name):
  """ Restarts all instances of a Google App Engine application on this machine.

  Args:
    app_name: The application ID corresponding to the app to restart.

  Returns:
    True if successful, and False otherwise.
  """
  if not misc.is_app_name_valid(app_name):
    logging.error("Unable to kill app process %s on because of " +\
                  "invalid name for application"%(app_name))
    return False

  logging.info("Restarting application %s"%app_name)
  watch = "app___" + app_name
  return monit_interface.restart(watch)
def stop_app_instance(app_name, port):
  """ Stops a Google App Engine application process instance on current 
      machine.

  Args:
    app_name: Name of application to stop
    port: The port the application is running on
  Returns:
    True on success, False otherwise
  """
  if not misc.is_app_name_valid(app_name):
    logging.error("Unable to kill app process %s on port %d because of " +\
                  "invalid name for application"%(app_name, int(port)))
    return False

  logging.info("Stopping application %s"%app_name)
  watch = "app___" + app_name + "-" + str(port)
  return monit_interface.stop(watch, is_group=False)
def restart_app_instances_for_app(app_name, language):
    """ Restarts all instances of a Google App Engine application on this machine.

  Args:
    app_name: The application ID corresponding to the app to restart.
    language: The language the application is written in.
  Returns:
    True if successful, and False otherwise.
  """
    if not misc.is_app_name_valid(app_name):
        logging.error("Unable to kill app process %s on because of " "invalid name for application" % (app_name))
        return False
    if language == "java":
        remove_conflicting_jars(app_name)
        copy_modified_jars(app_name)
    logging.info("Restarting application %s" % app_name)
    watch = "app___" + app_name
    return monit_interface.restart(watch)
def stop_app(app_name):
  """ Stops all process instances of a Google App Engine application on this 
      machine.

  Args:
    app_name: Name of application to stop
  Returns:
    True on success, False otherwise
  """

  if not misc.is_app_name_valid(app_name): 
    logging.error("Unable to kill app process %s on because of " +\
                  "invalid name for application"%(app_name))
    return False

  logging.info("Stopping application %s"%app_name)
  watch = "app___" + app_name 
  god_result = god_interface.stop(watch)
 
  if not god_result:
    logging.error("Unable to shut down god interface for watch %s"%watch)
    return False

  # hack: God fails to shutdown processes so we do it via a system command
  # TODO: fix it or find an alternative to god
  cmd = "ps -ef | grep \"dev_appserver\|AppServer_Java\" | grep " + \
        app_name + " | grep -v grep | grep cookie_secret | awk '{print $2}' " +\
        "| xargs kill -9"

  ret = os.system(cmd)
  if ret != 0:
    logging.error("Unable to shut down processes for app %s with exit value %d"\
                 %(app_name, ret))
    return False
  
  cmd = "rm -f " + constants.APP_PID_DIR + app_name + "-*"
  ret = os.system(cmd)
  if ret != 0:
    logging.error("Unable to remove PID files for app %s with exit value %d"\
                  %(app_name, ret))
    return False

  return True
Exemple #10
0
def stop_app(app_name):
    """ Stops all process instances of a Google App Engine application on this
      machine.

  Args:
    app_name: Name of application to stop
  Returns:
    True on success, False otherwise
  """
    if not misc.is_app_name_valid(app_name):
        logging.error("Unable to kill app process %s on because of " "invalid name for application" % (app_name))
        return False

    logging.info("Stopping application %s" % app_name)
    watch = "app___" + app_name
    monit_result = monit_interface.stop(watch)

    if not monit_result:
        logging.error("Unable to shut down monit interface for watch %s" % watch)
        return False

    return True
def start_app(config):
  """ Starts a Google App Engine application on this machine. It
      will start it up and then proceed to fetch the main page.

  Args:
    config: a dictionary that contains
       app_name: Name of the application to start
       app_port: Port to start on
       language: What language the app is written in
       load_balancer_ip: Public ip of load balancer
       xmpp_ip: IP of XMPP service
       env_vars: A dict of environment variables that should be passed to the
        app.
       max_memory: An int that names the maximum amount of memory that this
        App Engine app is allowed to consume before being restarted.
       syslog_server: The IP of the syslog server to send the application
         logs to. Usually it's the login private IP.
  Returns:
    PID of process on success, -1 otherwise
  """
  config = convert_config_from_json(config)
  if config == None:
    logging.error("Invalid configuration for application")
    return BAD_PID

  if not misc.is_app_name_valid(config['app_name']):
    logging.error("Invalid app name for application: " + config['app_name'])
    return BAD_PID
  logging.info("Starting %s application %s" % (
    config['language'], config['app_name']))

  env_vars = config['env_vars']
  env_vars['GOPATH'] = '/var/lib/appscale/AppServer/gopath/'
  env_vars['GOROOT'] = '/var/lib/appscale/AppServer/goroot/'
  watch = "app___" + config['app_name']

  if config['language'] == constants.PYTHON27 or \
      config['language'] == constants.GO or \
      config['language'] == constants.PHP:
    start_cmd = create_python27_start_cmd(
      config['app_name'],
      config['load_balancer_ip'],
      config['app_port'],
      config['load_balancer_ip'],
      config['xmpp_ip'])
    stop_cmd = create_python27_stop_cmd(config['app_port'])
    env_vars.update(create_python_app_env(
      config['load_balancer_ip'],
      config['app_name']))
  elif config['language'] == constants.JAVA:
    remove_conflicting_jars(config['app_name'])
    copy_successful = copy_modified_jars(config['app_name'])
    if not copy_successful:
      return BAD_PID
    start_cmd = create_java_start_cmd(
      config['app_name'],
      config['app_port'],
      config['load_balancer_ip'])
    stop_cmd = create_java_stop_cmd(config['app_port'])
    env_vars.update(create_java_app_env(config['app_name']))
  else:
    logging.error("Unknown application language %s for appname %s" \
      % (config['language'], config['app_name']))
    return BAD_PID

  logging.info("Start command: " + str(start_cmd))
  logging.info("Stop command: " + str(stop_cmd))
  logging.info("Environment variables: " + str(env_vars))

  # Set the syslog_server is specified.
  syslog_server = ""
  if 'syslog_server' in config:
    syslog_server = config['syslog_server']
  monit_app_configuration.create_config_file(
    str(watch),
    str(start_cmd),
    str(stop_cmd),
    [config['app_port']],
    env_vars,
    config['max_memory'],
    syslog_server,
    appscale_info.get_private_ip())

  if not monit_interface.start(watch):
    logging.error("Unable to start application server with monit")
    return BAD_PID

  if not wait_on_app(int(config['app_port'])):
    logging.error("Application server did not come up in time, "
      "removing monit watch")
    monit_interface.stop(watch)
    return BAD_PID

  threading.Thread(target=add_routing,
    args=(config['app_name'], config['app_port'])).start()

  if 'log_size' in config.keys():
    log_size = config['log_size']
  else:
    if config['app_name'] == APPSCALE_DASHBOARD_ID:
      log_size = DASHBOARD_LOG_SIZE
    else:
      log_size = APP_LOG_SIZE

  if not setup_logrotate(config['app_name'], watch, log_size):
    logging.error("Error while setting up log rotation for application: {}".
      format(config['app_name']))


  return 0
def start_app(config):
  """ Starts a Google App Engine application on this machine. It 
      will start it up and then proceed to fetch the main page.
  
  Args:
    config: a dictionary that contains 
       app_name: Name of the application to start
       app_port: Port to start on 
       language: What language the app is written in
       load_balancer_ip: Public ip of load balancer
       load_balancer_port: Port of load balancer
       xmpp_ip: IP of XMPP service 
       dblocations: List of database locations 
       env_vars: A dict of environment variables that should be passed to the
        app.
  Returns:
    PID of process on success, -1 otherwise
  """
  config = convert_config_from_json(config)
  if config == None:
    logging.error("Invalid configuration for application")
    return BAD_PID 
  
  if not misc.is_app_name_valid(config['app_name']):
    logging.error("Invalid app name for application: " +\
                  config['app_name'])
    return BAD_PID
  logging.info("Starting %s application %s"%(config['language'], 
                                             config['app_name']))

  start_cmd = ""
  stop_cmd = ""
  env_vars = config['env_vars']
  watch = "app___" + config['app_name']
 
  if config['language'] == constants.PYTHON or \
        config['language'] == constants.PYTHON27 or \
        config['language'] == constants.GO:
    start_cmd = create_python_start_cmd(config['app_name'],
                            config['load_balancer_ip'],
                            config['app_port'],
                            config['load_balancer_ip'],
                            config['load_balancer_port'],
                            config['xmpp_ip'],
                            config['dblocations'],
                            config['language'])
    logging.info(start_cmd)
    stop_cmd = create_python_stop_cmd(config['app_port'], config['language'])
    env_vars.update(create_python_app_env(config['load_balancer_ip'],
                            config['load_balancer_port'], 
                            config['app_name']))
  elif config['language'] == constants.JAVA:
    copy_successful = copy_modified_jars(config['app_name'])
    if not copy_successful:
      return BAD_PID
    start_cmd = create_java_start_cmd(config['app_name'],
                            config['app_port'],
                            config['load_balancer_ip'],
                            config['load_balancer_port'],
                            config['dblocations'])
    stop_cmd = create_java_stop_cmd(config['app_port'])
    env_vars.update(create_java_app_env())
  else:
    logging.error("Unknown application language %s for appname %s"\
                  %(config['language'], config['app_name'])) 
    return BAD_PID

  logging.info("Start command: " + str(start_cmd))
  logging.info("Stop command: " + str(stop_cmd))
  logging.info("Environment variables: " +str(env_vars))

  config_file_loc = god_app_configuration.create_config_file(str(watch),
                                                     str(start_cmd), 
                                                     str(stop_cmd), 
                                                     [config['app_port']],
                                                     env_vars)

  if not god_interface.start(config_file_loc, watch):
    logging.error("Unable to start application server with god")
    return BAD_PID

  if not wait_on_app(int(config['app_port'])):
    logging.error("Application server did not come up in time, " + \
                   "removing god watch")
    god_interface.stop(watch)
    return BAD_PID

  pid = get_pid_from_port(config['app_port'])
  pid_file = constants.APP_PID_DIR + config['app_name'] + '-' +\
             str(config['app_port'])
  file_io.write(pid_file, str(pid))
      
  return pid
Exemple #13
0
def start_app(config):
    """ Starts a Google App Engine application on this machine. It 
      will start it up and then proceed to fetch the main page.
  
  Args:
    config: a dictionary that contains 
       app_name: Name of the application to start
       app_port: Port to start on 
       language: What language the app is written in
       load_balancer_ip: Public ip of load balancer
       load_balancer_port: Port of load balancer
       xmpp_ip: IP of XMPP service 
       dblocations: List of database locations 
       env_vars: A dict of environment variables that should be passed to the
        app.
  Returns:
    PID of process on success, -1 otherwise
  """
    config = convert_config_from_json(config)
    if config == None:
        logging.error("Invalid configuration for application")
        return BAD_PID

    if not misc.is_app_name_valid(config['app_name']):
        logging.error("Invalid app name for application: " +\
                      config['app_name'])
        return BAD_PID
    logging.info("Starting %s application %s" %
                 (config['language'], config['app_name']))

    start_cmd = ""
    stop_cmd = ""
    env_vars = config['env_vars']
    watch = "app___" + config['app_name']

    if config['language'] == constants.PYTHON or \
          config['language'] == constants.PYTHON27 or \
          config['language'] == constants.GO:
        start_cmd = create_python_start_cmd(
            config['app_name'], config['load_balancer_ip'], config['app_port'],
            config['load_balancer_ip'], config['load_balancer_port'],
            config['xmpp_ip'], config['dblocations'], config['language'])
        logging.info(start_cmd)
        stop_cmd = create_python_stop_cmd(config['app_port'],
                                          config['language'])
        env_vars.update(
            create_python_app_env(config['load_balancer_ip'],
                                  config['load_balancer_port'],
                                  config['app_name']))
    elif config['language'] == constants.JAVA:
        copy_successful = copy_modified_jars(config['app_name'])
        if not copy_successful:
            return BAD_PID
        start_cmd = create_java_start_cmd(config['app_name'],
                                          config['app_port'],
                                          config['load_balancer_ip'],
                                          config['load_balancer_port'],
                                          config['dblocations'])
        stop_cmd = create_java_stop_cmd(config['app_port'])
        env_vars.update(create_java_app_env())
    else:
        logging.error("Unknown application language %s for appname %s"\
                      %(config['language'], config['app_name']))
        return BAD_PID

    logging.info("Start command: " + str(start_cmd))
    logging.info("Stop command: " + str(stop_cmd))
    logging.info("Environment variables: " + str(env_vars))

    config_file_loc = god_app_configuration.create_config_file(
        str(watch), str(start_cmd), str(stop_cmd), [config['app_port']],
        env_vars)

    if not god_interface.start(config_file_loc, watch):
        logging.error("Unable to start application server with god")
        return BAD_PID

    if not wait_on_app(int(config['app_port'])):
        logging.error("Application server did not come up in time, " + \
                       "removing god watch")
        god_interface.stop(watch)
        return BAD_PID

    pid = get_pid_from_port(config['app_port'])
    pid_file = constants.APP_PID_DIR + config['app_name'] + '-' +\
               str(config['app_port'])
    file_io.write(pid_file, str(pid))

    return pid
def start_app(config):
    """ Starts a Google App Engine application on this machine. It
      will start it up and then proceed to fetch the main page.

  Args:
    config: a dictionary that contains
       app_name: Name of the application to start
       app_port: Port to start on
       language: What language the app is written in
       load_balancer_ip: Public ip of load balancer
       xmpp_ip: IP of XMPP service
       env_vars: A dict of environment variables that should be passed to the
        app.
       max_memory: An int that names the maximum amount of memory that this
        App Engine app is allowed to consume before being restarted.
       syslog_server: The IP of the syslog server to send the application
         logs to. Usually it's the login private IP.
  Returns:
    PID of process on success, -1 otherwise
  """
    config = convert_config_from_json(config)
    if config is None:
        logging.error("Invalid configuration for application")
        return BAD_PID

    if not misc.is_app_name_valid(config['app_name']):
        logging.error("Invalid app name for application: " +
                      config['app_name'])
        return BAD_PID
    logging.info("Starting %s application %s" %
                 (config['language'], config['app_name']))

    env_vars = config['env_vars']
    env_vars['GOPATH'] = '/root/appscale/AppServer/gopath/'
    env_vars['GOROOT'] = '/root/appscale/AppServer/goroot/'
    watch = "app___" + config['app_name']

    if config['language'] == constants.PYTHON27 or \
        config['language'] == constants.GO or \
        config['language'] == constants.PHP:
        start_cmd = create_python27_start_cmd(config['app_name'],
                                              config['load_balancer_ip'],
                                              config['app_port'],
                                              config['load_balancer_ip'],
                                              config['xmpp_ip'])
        stop_cmd = create_python27_stop_cmd(config['app_port'])
        env_vars.update(
            create_python_app_env(config['load_balancer_ip'],
                                  config['app_name']))
    elif config['language'] == constants.JAVA:
        remove_conflicting_jars(config['app_name'])
        copy_successful = copy_modified_jars(config['app_name'])
        if not copy_successful:
            return BAD_PID

        # Account for MaxPermSize (~170MB), the parent process (~50MB), and thread
        # stacks (~20MB).
        max_heap = config['max_memory'] - 250
        if max_heap <= 0:
            return BAD_PID
        start_cmd = create_java_start_cmd(config['app_name'],
                                          config['app_port'],
                                          config['load_balancer_ip'], max_heap)

        stop_cmd = create_java_stop_cmd(config['app_port'])
        env_vars.update(create_java_app_env(config['app_name']))
    else:
        logging.error("Unknown application language %s for appname %s" \
          % (config['language'], config['app_name']))
        return BAD_PID

    logging.info("Start command: " + str(start_cmd))
    logging.info("Stop command: " + str(stop_cmd))
    logging.info("Environment variables: " + str(env_vars))

    # Set the syslog_server is specified.
    syslog_server = ""
    if 'syslog_server' in config:
        syslog_server = config['syslog_server']
    monit_app_configuration.create_config_file(str(watch), str(start_cmd),
                                               str(stop_cmd),
                                               [config['app_port']], env_vars,
                                               config['max_memory'],
                                               syslog_server,
                                               appscale_info.get_private_ip())

    if not monit_interface.start(watch):
        logging.error("Unable to start application server with monit")
        return BAD_PID

    if not wait_on_app(int(config['app_port'])):
        logging.error("Application server did not come up in time, "
                      "removing monit watch")
        monit_interface.stop(watch)
        return BAD_PID

    threading.Thread(target=add_routing,
                     args=(config['app_name'], config['app_port'])).start()

    if 'log_size' in config.keys():
        log_size = config['log_size']
    else:
        if config['app_name'] == APPSCALE_DASHBOARD_ID:
            log_size = DASHBOARD_LOG_SIZE
        else:
            log_size = APP_LOG_SIZE

    if not setup_logrotate(config['app_name'], watch, log_size):
        logging.error(
            "Error while setting up log rotation for application: {}".format(
                config['app_name']))

    return 0
def start_app(config):
  """ Starts a Google App Engine application on this machine. It
      will start it up and then proceed to fetch the main page.

  Args:
    config: a dictionary that contains
       app_name: Name of the application to start
       app_port: Port to start on
       language: What language the app is written in
       load_balancer_ip: Public ip of load balancer
       xmpp_ip: IP of XMPP service
       env_vars: A dict of environment variables that should be passed to the
        app.
       max_memory: An int that names the maximum amount of memory that this
        App Engine app is allowed to consume before being restarted.
       syslog_server: The IP of the syslog server to send the application
         logs to. Usually it's the login private IP.
  Returns:
    PID of process on success, -1 otherwise
  """
  config = convert_config_from_json(config)
  if config == None:
    logging.error("Invalid configuration for application")
    return BAD_PID

  if not misc.is_app_name_valid(config['app_name']):
    logging.error("Invalid app name for application: " + config['app_name'])
    return BAD_PID
  logging.info("Starting %s application %s" % (
    config['language'], config['app_name']))

  start_cmd = ""
  stop_cmd = ""
  env_vars = config['env_vars']
  env_vars['GOPATH'] = '/root/appscale/AppServer/gopath/'
  env_vars['GOROOT'] = '/root/appscale/AppServer/goroot/'
  watch = "app___" + config['app_name']

  if config['language'] == constants.PYTHON27 or \
      config['language'] == constants.GO or \
      config['language'] == constants.PHP:
    start_cmd = create_python27_start_cmd(
      config['app_name'],
      config['load_balancer_ip'],
      config['app_port'],
      config['load_balancer_ip'],
      config['xmpp_ip'])
    logging.info(start_cmd)
    stop_cmd = create_python27_stop_cmd(config['app_port'])
    env_vars.update(create_python_app_env(
      config['load_balancer_ip'],
      config['app_name']))
  elif config['language'] == constants.JAVA:
    remove_conflicting_jars(config['app_name'])
    copy_successful = copy_modified_jars(config['app_name'])
    if not copy_successful:
      return BAD_PID
    start_cmd = create_java_start_cmd(
      config['app_name'],
      config['app_port'],
      config['load_balancer_ip'])
    stop_cmd = create_java_stop_cmd(config['app_port'])
    env_vars.update(create_java_app_env(config['app_name']))
  else:
    logging.error("Unknown application language %s for appname %s" \
      % (config['language'], config['app_name']))
    return BAD_PID

  logging.info("Start command: " + str(start_cmd))
  logging.info("Stop command: " + str(stop_cmd))
  logging.info("Environment variables: " + str(env_vars))

  # Set the syslog_server is specified.
  syslog_server = ""
  if 'syslog_server' in config:
    syslog_server = config['syslog_server']
  monit_app_configuration.create_config_file(
    str(watch),
    str(start_cmd),
    str(stop_cmd),
    [config['app_port']],
    env_vars,
    config['max_memory'],
    syslog_server)

  if not monit_interface.start(watch):
    logging.error("Unable to start application server with monit")
    return BAD_PID

  if not wait_on_app(int(config['app_port'])):
    logging.error("Application server did not come up in time, "
      "removing monit watch")
    monit_interface.stop(watch)
    return BAD_PID

  return 0
def start_app(config):
  """ Starts a Google App Engine application on this machine. It
      will start it up and then proceed to fetch the main page.

  Args:
    config: a dictionary that contains
       app_name: Name of the application to start
       app_port: Port to start on
       language: What language the app is written in
       load_balancer_ip: Public ip of load balancer
       xmpp_ip: IP of XMPP service
       dblocations: List of database locations
       env_vars: A dict of environment variables that should be passed to the
        app.
       max_memory: An int that names the maximum amount of memory that this
        App Engine app is allowed to consume before being restarted.
  Returns:
    PID of process on success, -1 otherwise
  """
  config = convert_config_from_json(config)
  if config == None:
    logging.error("Invalid configuration for application")
    return BAD_PID

  if not misc.is_app_name_valid(config['app_name']):
    logging.error("Invalid app name for application: " +\
                  config['app_name'])
    return BAD_PID
  logging.info("Starting %s application %s"%(config['language'],
                                             config['app_name']))

  start_cmd = ""
  stop_cmd = ""
  env_vars = config['env_vars']
  env_vars['GOPATH'] = '/root/appscale/AppServer/gopath/'
  env_vars['GOROOT'] = '/root/appscale/AppServer/goroot/'
  watch = "app___" + config['app_name']

  if config['language'] == constants.PYTHON27 or \
       config['language'] == constants.GO or \
       config['language'] == constants.PHP:
    start_cmd = create_python27_start_cmd(config['app_name'],
                            config['load_balancer_ip'],
                            config['app_port'],
                            config['load_balancer_ip'],
                            config['xmpp_ip'])
    logging.info(start_cmd)
    stop_cmd = create_python27_stop_cmd(config['app_port'])
    env_vars.update(create_python_app_env(config['load_balancer_ip'],
                            config['app_name']))
  elif config['language'] == constants.JAVA:
    remove_conflicting_jars(config['app_name'])
    copy_successful = copy_modified_jars(config['app_name'])
    if not copy_successful:
      return BAD_PID
    start_cmd = create_java_start_cmd(config['app_name'],
                            config['app_port'],
                            config['load_balancer_ip'])
    stop_cmd = create_java_stop_cmd(config['app_port'])
    env_vars.update(create_java_app_env())
  else:
    logging.error("Unknown application language %s for appname %s"\
                  %(config['language'], config['app_name']))
    return BAD_PID

  logging.info("Start command: " + str(start_cmd))
  logging.info("Stop command: " + str(stop_cmd))
  logging.info("Environment variables: " +str(env_vars))

  monit_app_configuration.create_config_file(str(watch),
                                             str(start_cmd),
                                             str(stop_cmd),
                                             [config['app_port']],
                                             env_vars,
                                             config['max_memory'])

  if not monit_interface.start(watch):
    logging.error("Unable to start application server with monit")
    return BAD_PID

  if not wait_on_app(int(config['app_port'])):
    logging.error("Application server did not come up in time, " + \
                   "removing monit watch")
    monit_interface.stop(watch)
    return BAD_PID

  return 0
Exemple #17
0
def start_app(config):
  """ Starts a Google App Engine application on this machine. It
      will start it up and then proceed to fetch the main page.

  Args:
    config: a dictionary that contains
       app_name: Name of the application to start
       app_port: Port to start on
       language: What language the app is written in
       load_balancer_ip: Public ip of load balancer
       xmpp_ip: IP of XMPP service
       env_vars: A dict of environment variables that should be passed to the
        app.
       max_memory: An int that names the maximum amount of memory that this
        App Engine app is allowed to consume before being restarted.
       syslog_server: The IP of the syslog server to send the application
         logs to. Usually it's the login private IP.
  Returns:
    PID of process on success, -1 otherwise
  """
  config = convert_config_from_json(config)
  if config is None:
    logging.error("Invalid configuration for application")
    return BAD_PID

  if not misc.is_app_name_valid(config['app_name']):
    logging.error("Invalid app name for application: " + config['app_name'])
    return BAD_PID
  logging.info("Starting %s application %s" % (
    config['language'], config['app_name']))

  env_vars = config['env_vars']
  env_vars['GOPATH'] = '/root/appscale/AppServer/gopath/'
  env_vars['GOROOT'] = '/root/appscale/AppServer/goroot/'
  watch = "app___" + config['app_name']
  match_cmd = ""

  if config['language'] == constants.PYTHON27 or \
      config['language'] == constants.GO or \
      config['language'] == constants.PHP:
    start_cmd = create_python27_start_cmd(
      config['app_name'],
      config['load_balancer_ip'],
      config['app_port'],
      config['load_balancer_ip'],
      config['xmpp_ip'])
    stop_cmd = create_python27_stop_cmd(config['app_port'])
    env_vars.update(create_python_app_env(
      config['load_balancer_ip'],
      config['app_name']))
  elif config['language'] == constants.JAVA:
    remove_conflicting_jars(config['app_name'])
    copy_successful = copy_modified_jars(config['app_name'])
    if not copy_successful:
      return BAD_PID

    # Account for MaxPermSize (~170MB), the parent process (~50MB), and thread
    # stacks (~20MB).
    max_heap = config['max_memory'] - 250
    if max_heap <= 0:
      return BAD_PID
    start_cmd = create_java_start_cmd(
      config['app_name'],
      config['app_port'],
      config['load_balancer_ip'],
      max_heap
    )
    match_cmd = "java -ea -cp.*--port={}.*{}".format(str(config['app_port']),
      os.path.dirname(locate_dir("/var/apps/" + config['app_name'] + "/app/",
      "WEB-INF")))

    stop_cmd = create_java_stop_cmd(config['app_port'])
    env_vars.update(create_java_app_env(config['app_name']))
  else:
    logging.error("Unknown application language %s for appname %s" \
      % (config['language'], config['app_name']))
    return BAD_PID

  logging.info("Start command: " + str(start_cmd))
  logging.info("Stop command: " + str(stop_cmd))
  logging.info("Environment variables: " + str(env_vars))

  # Set the syslog_server is specified.
  syslog_server = ""
  if 'syslog_server' in config:
    syslog_server = config['syslog_server']
  monit_app_configuration.create_config_file(
    str(watch),
    str(start_cmd),
    str(stop_cmd),
    [config['app_port']],
    env_vars,
    config['max_memory'],
    syslog_server,
    appscale_info.get_private_ip(),
    match_cmd=match_cmd)

  # We want to tell monit to start the single process instead of the
  # group, since monit can get slow if there are quite a few processes in
  # the same group.
  full_watch = "{}-{}".format(str(watch), str(config['app_port']))
  if not monit_interface.start(full_watch, is_group=False):
    logging.warning("Monit was unable to start {}:{}".
      format(str(config['app_name']), config['app_port']))
    return BAD_PID

  # Since we are going to wait, possibly for a long time for the
  # application to be ready, we do it in a thread.
  threading.Thread(target=add_routing,
    args=(config['app_name'], config['app_port'])).start()

  if 'log_size' in config.keys():
    log_size = config['log_size']
  else:
    if config['app_name'] == APPSCALE_DASHBOARD_ID:
      log_size = DASHBOARD_LOG_SIZE
    else:
      log_size = APP_LOG_SIZE

  if not setup_logrotate(config['app_name'], watch, log_size):
    logging.error("Error while setting up log rotation for application: {}".
      format(config['app_name']))

  return 0