Example #1
0
    def send(self, nodes_stats):
        deployment_id = helper.get_deployment_id()
        # If the deployment is not registered, skip.
        if not deployment_id:
            return

        # Send request to AppScale Portal.
        portal_path = self._portal_method.format(deployment_id=deployment_id)
        url = "{0}{1}".format(constants.PORTAL_URL, portal_path)
        data = {
            'deployment_id':
            deployment_id,
            'nodes_stats':
            json.dumps({
                node_ip: [stats_to_dict(snapshot) for snapshot in snapshots]
                for node_ip, snapshots in nodes_stats.iteritems()
            })
        }
        snapshots_num = sum(
            len(snapshots) for snapshots in nodes_stats.values())
        logger.debug(
            "Sending {snapshots} node stats snapshots about {nodes} nodes to the "
            "AppScale Portal".format(snapshots=snapshots_num,
                                     nodes=len(nodes_stats)))

        request = helper.create_request(url=url,
                                        method='POST',
                                        body=urllib.urlencode(data))
        response = helper.urlfetch(request)

        if not response[JSONTags.SUCCESS]:
            logger.error("Inaccessible resource: {}".format(url))
            return
Example #2
0
def poll():
    """ Callback function that polls for new tasks based on a schedule. """
    deployment_id = helper.get_deployment_id()
    # If the deployment is not registered, skip.
    if not deployment_id:
        return

    # If we can't reach the backup and recovery services, skip.
    nodes = helper.get_node_info()
    http_client = tornado.httpclient.HTTPClient()
    for node in nodes:
        br_host = node[helper.NodeInfoTags.HOST]
        request = tornado.httpclient.HTTPRequest(br_host)
        try:
            response = http_client.fetch(request)
            if json.loads(response.body)['status'] != 'up':
                logging.warn(
                    'Backup and Recovery service at {} is not up.'.format(
                        br_host))
                return
        except (socket.error, ValueError):
            logging.exception(
                'Backup and Recovery service at {} is not up.'.format(br_host))
            return

    logging.info("Polling for new task.")

    # Send request to AppScale Portal.
    url = "{0}{1}".format(constants.PORTAL_URL, constants.PORTAL_POLL_PATH)
    data = urllib.urlencode({JSONTags.DEPLOYMENT_ID: deployment_id})
    request = helper.create_request(url=url, method='POST', body=data)
    response = helper.urlfetch(request)

    if not response[JSONTags.SUCCESS]:
        logging.error("Inaccessible resource: {}".format(url))
        return

    try:
        data = json.loads(response[JSONTags.BODY])
    except (TypeError, ValueError) as error:
        logging.error(
            "Cannot parse response from url '{0}'. Error: {1}".format(
                url, str(error)))
        return

    if data == {}:  # If there's no task to perform.
        return

    # Verify all necessary fields are present in the request.
    if not set(data.keys()).issuperset(set(constants.REQUIRED_KEYS)):
        logging.error("Missing args in response: {0}".format(response))
        return

    logging.debug("Task to run: {0}".format(data))
    logging.info("Redirecting task request to TaskHandler.")
    url = "http://localhost:{}{}".format(constants.HERMES_PORT, '/do_task')
    request = helper.create_request(url, method='POST', body=json.dumps(data))

    # The poller can move forward without waiting for a response here.
    helper.urlfetch_async(request)
Example #3
0
  def send(self, nodes_stats):
    deployment_id = helper.get_deployment_id()
    # If the deployment is not registered, skip.
    if not deployment_id:
      return

    # Send request to AppScale Portal.
    portal_path = self._portal_method.format(deployment_id=deployment_id)
    url = "{0}{1}".format(constants.PORTAL_URL, portal_path)
    data = {
      'deployment_id': deployment_id,
      'nodes_stats': json.dumps({
        node_ip: [stats_to_dict(snapshot) for snapshot in snapshots]
        for node_ip, snapshots in nodes_stats.iteritems()
      })
    }
    snapshots_num = sum(len(snapshots) for snapshots in nodes_stats.values())
    logging.debug(
      "Sending {snapshots} node stats snapshots about {nodes} nodes to the "
      "AppScale Portal".format(snapshots=snapshots_num, nodes=len(nodes_stats))
    )

    request = helper.create_request(url=url, method='POST',
                                    body=urllib.urlencode(data))
    response = helper.urlfetch(request)

    if not response[JSONTags.SUCCESS]:
      logging.error("Inaccessible resource: {}".format(url))
      return
Example #4
0
def poll():
  """ Callback function that polls for new tasks based on a schedule. """
  deployment_id = helper.get_deployment_id()
  # If the deployment is not registered, skip.
  if not deployment_id:
    return

  # If we can't reach the backup and recovery services, skip.
  nodes = helper.get_node_info()
  http_client = tornado.httpclient.HTTPClient()
  for node in nodes:
    br_host = node[helper.NodeInfoTags.HOST]
    request = tornado.httpclient.HTTPRequest(br_host)
    try:
      response = http_client.fetch(request)
      if json.loads(response.body)['status'] != 'up':
        logging.warn('Backup and Recovery service at {} is not up.'
          .format(br_host))
        return
    except (socket.error, ValueError):
      logging.exception('Backup and Recovery service at {} is not up.'
        .format(br_host))
      return

  logging.info("Polling for new task.")

  # Send request to AppScale Portal.
  url = "{0}{1}".format(constants.PORTAL_URL,
                        constants.PORTAL_POLL_PATH)
  data = urllib.urlencode({JSONTags.DEPLOYMENT_ID: deployment_id})
  request = helper.create_request(url=url, method='POST', body=data)
  response = helper.urlfetch(request)

  if not response[JSONTags.SUCCESS]:
    logging.error("Inaccessible resource: {}".format(url))
    return

  try:
    data = json.loads(response[JSONTags.BODY])
  except (TypeError, ValueError) as error:
    logging.error("Cannot parse response from url '{0}'. Error: {1}".
      format(url, str(error)))
    return

  if data == {}:  # If there's no task to perform.
    return

  # Verify all necessary fields are present in the request.
  if not set(data.keys()).issuperset(set(constants.REQUIRED_KEYS)):
    logging.error("Missing args in response: {0}".format(response))
    return

  logging.debug("Task to run: {0}".format(data))
  logging.info("Redirecting task request to TaskHandler.")
  url = "http://localhost:{}{}".format(constants.HERMES_PORT, '/do_task')
  request = helper.create_request(url, method='POST', body=json.dumps(data))

  # The poller can move forward without waiting for a response here.
  helper.urlfetch_async(request)
Example #5
0
    def test_get_deployment_id(self):
        # Test with a registered AppScale deployment.
        fake_acc = FakeAppControllerClient(True)
        flexmock(appscale_info).should_receive('get_appcontroller_client').\
          and_return(fake_acc)
        flexmock(AppControllerClient).should_receive('deployment_id_exists').\
          and_return(True)
        flexmock(AppControllerClient).should_receive('get_deployment_id').\
          and_return('fake_id')
        self.assertEquals('fake_id', helper.get_deployment_id())

        # Test with an AppScale deployment that's not registered.
        fake_acc = FakeAppControllerClient(False)
        flexmock(appscale_info).should_receive('get_appcontroller_client').\
          and_return(fake_acc)
        flexmock(AppControllerClient).should_receive('deployment_id_exists').\
          and_return(False)
        self.assertIsNone(helper.get_deployment_id())
Example #6
0
  def test_get_deployment_id(self):
    # Test with a registered AppScale deployment.
    fake_acc = FakeAppControllerClient(True)
    flexmock(appscale_info).should_receive('get_appcontroller_client').\
      and_return(fake_acc)
    flexmock(AppControllerClient).should_receive('deployment_id_exists').\
      and_return(True)
    flexmock(AppControllerClient).should_receive('get_deployment_id').\
      and_return('fake_id')
    self.assertEquals('fake_id', helper.get_deployment_id())

    # Test with an AppScale deployment that's not registered.
    fake_acc = FakeAppControllerClient(False)
    flexmock(appscale_info).should_receive('get_appcontroller_client').\
      and_return(fake_acc)
    flexmock(AppControllerClient).should_receive('deployment_id_exists').\
      and_return(False)
    self.assertIsNone(helper.get_deployment_id())
Example #7
0
    def deploy(self):
        """ Uploads the sensor app for registered deployments. """
        deployment_id = helper.get_deployment_id()
        # If deployment is not registered, then do nothing.
        if not deployment_id:
            return

        ua_client = UAClient(appscale_info.get_db_master_ip(), options.secret)

        # If the appscalesensor app is already running, then do nothing.
        version_node = '/appscale/projects/{}/services/{}/versions/{}'.format(
            constants.APPSCALE_SENSOR, DEFAULT_SERVICE, DEFAULT_VERSION)
        if self.zk_client.exists(version_node) is not None:
            return

        pwd = appscale_utils.encrypt_password(
            constants.USER_EMAIL, appscale_utils.random_password_generator())
        if create_appscale_user(pwd, ua_client) and create_xmpp_user(
                pwd, ua_client):
            logging.debug(
                "Created new user and now tarring app to be deployed.")
            file_path = os.path.join(os.path.dirname(__file__),
                                     '../Apps/sensor')
            app_dir_location = os.path.join(constants.APP_DIR_LOCATION,
                                            constants.APPSCALE_SENSOR)
            archive = tarfile.open(app_dir_location, "w|gz")
            archive.add(file_path, arcname=constants.APPSCALE_SENSOR)
            archive.close()

            try:
                logging.info(
                    "Deploying the sensor app for registered deployments.")
                acc = appscale_info.get_appcontroller_client()
                acc.upload_app(app_dir_location, constants.FILE_SUFFIX)
            except AppControllerException:
                logging.exception(
                    "AppControllerException while trying to deploy "
                    "appscalesensor app.")
        else:
            logging.error(
                "Error while creating or accessing the user to deploy "
                "appscalesensor app.")
Example #8
0
  def deploy(self):
    """ Uploads the sensor app for registered deployments. """
    deployment_id = helper.get_deployment_id()
    # If deployment is not registered, then do nothing.
    if not deployment_id:
      return

    ua_client = UAClient(appscale_info.get_db_master_ip(), options.secret)

    # If the appscalesensor app is already running, then do nothing.
    version_node = '/appscale/projects/{}/services/{}/versions/{}'.format(
      constants.APPSCALE_SENSOR, DEFAULT_SERVICE, DEFAULT_VERSION)
    if self.zk_client.exists(version_node) is not None:
      return

    pwd = appscale_utils.encrypt_password(constants.USER_EMAIL,
                                          appscale_utils.random_password_generator())
    if create_appscale_user(pwd, ua_client) and create_xmpp_user(pwd,
                                                                 ua_client):
      logging.debug("Created new user and now tarring app to be deployed.")
      file_path = os.path.join(os.path.dirname(__file__), '../Apps/sensor')
      app_dir_location = os.path.join(constants.APP_DIR_LOCATION,
                                      constants.APPSCALE_SENSOR)
      archive = tarfile.open(app_dir_location, "w|gz")
      archive.add(file_path, arcname=constants.APPSCALE_SENSOR)
      archive.close()

      try:
        logging.info("Deploying the sensor app for registered deployments.")
        acc = appscale_info.get_appcontroller_client()
        acc.upload_app(app_dir_location, constants.FILE_SUFFIX)
      except AppControllerException:
        logging.exception("AppControllerException while trying to deploy "
                          "appscalesensor app.")
    else:
      logging.error("Error while creating or accessing the user to deploy "
                    "appscalesensor app.")