Esempio n. 1
0
    def __init__(self,
                 geni_username,
                 vessel_count,
                 vessel_type,
                 program_filename,
                 log_filename=None):
        """
    <Purpose>
      Initializes an instance of Overlord for the deployment of an arbitrary service.
      Populates the instance's configuration dictionary, which can be accessed from
      the object if data is needed for the run() function

    <Arguments>
      geni_username
        SeattleGENI username. Used to locate and handle public and private key
        files.
      vesselcount
        The number of vessels on which to deploy.
      vesseltype
        The type of vessel to acquire, based on the SEATTLECLEARINGHOUSE_VESSEL_TYPE_*
        constants within experimentlib.py
      program_filename
        The filename of the program to deploy and monitor on vessels.
      log_filename
        The file the user wants overlord to log to. If None, logs directly to
        console

    <Exceptions>
      ValueError
        Raised if argument vesseltype doesn't match one of the experimentlib
        SEATTLECLEARINGHOUSE_VESSEL_TYPE_* constants, if argument program file does not
        exist, or if argument number of vessels on which to deploy exceeds the
        user's number of vessel credits.

    <Side Effects>
      Initializes certain global variables.
      Removes 'stop' file from directory if it exists
      Sets the functions that makes up run() to the default methods listed at the
      end of the code.
    
    <Returns>
      None
    """
        # If a stop file still exists, delete it for the user
        if os.path.isfile("./stop"):
            os.remove(os.path.expanduser("./stop"))

        # List of valid vessel types.
        vessel_types = [
            explib.SEATTLECLEARINGHOUSE_VESSEL_TYPE_WAN,
            explib.SEATTLECLEARINGHOUSE_VESSEL_TYPE_LAN,
            explib.SEATTLECLEARINGHOUSE_VESSEL_TYPE_NAT,
            explib.SEATTLECLEARINGHOUSE_VESSEL_TYPE_RAND
        ]

        if vessel_type not in vessel_types:
            raise ValueError(
                "Invalid vessel type specified. Argument 'vessel_type' must be one of "
                +
                "the SEATTLECLEARINGHOUSE_VESSEL_TYPE_* constants defined in 'experimentlib.py'"
            )

        self.config['vessel_type'] = vessel_type

        # If a program file isn't passed, assume user will handle the issue
        if program_filename:
            # Verify that program file exists
            if not os.path.isfile(program_filename):
                raise ValueError("Specified program file '" +
                                 program_filename + "' does not exist")

            self.config['program_filename'] = program_filename

        # Setup explib identity object and GENI details
        self.config['identity'] = explib.create_identity_from_key_files(
            geni_username + '.publickey', geni_username + '.privatekey')
        self.config['geni_port'] = explib.seattlegeni_user_port(
            self.config['identity'])

        # Ensure that the user has enough credits to acquire the specified number of vessels.
        num_vessel_credits = explib.seattlegeni_max_vessels_allowed(
            self.config['identity'])

        if vessel_count > num_vessel_credits:
            raise ValueError(
                "Invalid number of vessels specified. The number of deployed vessels must "
                +
                "be less than or equal to the user's number of vessel credits."
            )

        self.config['vessel_count'] = vessel_count

        # Set up the logger according to passed arguments
        if log_filename:
            # Add the file logger.
            fileLog = logging.FileHandler(log_filename, 'w')
            fileLog.setFormatter(
                logging.Formatter('%(asctime)s %(levelname)-8s %(message)s',
                                  '%Y-%m-%d %H:%M:%S'))
            self.logger.addHandler(fileLog)
        else:
            # Add the console logger.
            consoleLog = logging.StreamHandler()
            consoleLog.setFormatter(
                logging.Formatter('%(asctime)s %(levelname)-8s %(message)s',
                                  '%H:%M:%S'))
            self.logger.addHandler(consoleLog)

        # Setting the functions of 'run' to default
        self.init_overlord_func = default_init_overlord
        self.acquire_vessels_func = default_acquire_vessels
        self.init_vessels_func = default_initiate_vessels
        self.remove_vessels_func = default_remove_vessels
        self.maintenance_func = default_maintenance
Esempio n. 2
0
def init(geni_username, vesselcount, vesseltype, program_filename):
  """
  <Purpose>
    Initializes the deployment of an arbitrary service. Populates a global
    configuration dictionary and returns a dict of data that could be required
    by the run() function. init() must be called before the run() function.

    Note on the return dict:
      The return value of init() is meant to contain data that is needed by
      calls to explib.start_vessel() within the run() function. At the time of
      creation of this library, the only such data that is required by
      deployable services is the user's GENI port.

      To add support for services requiring more arguments, simply add the
      necessary data to the dictionary returned by this function.

  <Arguments>
    geni_username
      SeattleGENI username. Used to locate and handle public and private key
      files.
    vesselcount
      The number of vessels on which to deploy.
    vesseltype
      The type of vessel to acquire, based on the SEATTLEGENI_VESSEL_TYPE_*
      constants within experimentlib.py
    program_filename
      The filename of the program to deploy and monitor on vessels.

  <Exceptions>
    ValueError
      Raised if argument vesseltype doesn't match one of the experimentlib
      SEATTLEGENI_VESSEL_TYPE_* constants, if argument program file does not
      exist, or if argument number of vessels on which to deploy exceeds the
      user's number of vessel credits.

  <Side Effects>
    Initializes certain global variables.
    
  <Returns>
    A dictionary containing data that clients might need for running program on
    vessels.
  """
  
  # Fill config dict with argument data
  # Validate vesseltype, based on constants in explib
  if vesseltype not in [explib.SEATTLEGENI_VESSEL_TYPE_WAN,
                        explib.SEATTLEGENI_VESSEL_TYPE_LAN,
                        explib.SEATTLEGENI_VESSEL_TYPE_NAT,
                        explib.SEATTLEGENI_VESSEL_TYPE_RAND]:
    raise ValueError('Invalid vessel type specified. Argument vessel type must be one of the SEATTLEGENI_VESSEL_TYPE_* constants defined in experimentlib.py')
  config['vesseltype'] = vesseltype
    
  # Verify that program file exists
  if not os.path.isfile(program_filename):
    raise ValueError('Specified program file ' + program_filename + ' does not exist')
  config['program_filename'] = program_filename
    
  # Setup explib identity object and GENI details
  config['identity'] = explib.create_identity_from_key_files(
    geni_username + '.publickey',
    geni_username + '.privatekey')
  print config['identity']
  config['geni_port'] = explib.seattlegeni_user_port(config['identity'])
  
  # Validate number of vessels on which to deploy
  num_vslcredits = explib.seattlegeni_max_vessels_allowed(config['identity'])
  if vesselcount > num_vslcredits:
    raise ValueError('Invalid number of vessels specified. The number of deployed vessels must be less than or equal to the user\'s number of vessel credits.')
  config['vesselcount'] = vesselcount


  # Create and populate the return dict
  ret_dict = {
    'geni_port': config['geni_port']
    }

  return ret_dict
Esempio n. 3
0
    def __init__(self, geni_username, vessel_count, vessel_type, program_filename, log_filename=None):
        """
    <Purpose>
      Initializes an instance of Overlord for the deployment of an arbitrary service.
      Populates the instance's configuration dictionary, which can be accessed from
      the object if data is needed for the run() function

    <Arguments>
      geni_username
        SeattleGENI username. Used to locate and handle public and private key
        files.
      vesselcount
        The number of vessels on which to deploy.
      vesseltype
        The type of vessel to acquire, based on the SEATTLECLEARINGHOUSE_VESSEL_TYPE_*
        constants within experimentlib.py
      program_filename
        The filename of the program to deploy and monitor on vessels.
      log_filename
        The file the user wants overlord to log to. If None, logs directly to
        console

    <Exceptions>
      ValueError
        Raised if argument vesseltype doesn't match one of the experimentlib
        SEATTLECLEARINGHOUSE_VESSEL_TYPE_* constants, if argument program file does not
        exist, or if argument number of vessels on which to deploy exceeds the
        user's number of vessel credits.

    <Side Effects>
      Initializes certain global variables.
      Removes 'stop' file from directory if it exists
      Sets the functions that makes up run() to the default methods listed at the
      end of the code.
    
    <Returns>
      None
    """
        # If a stop file still exists, delete it for the user
        if os.path.isfile("./stop"):
            os.remove(os.path.expanduser("./stop"))

        # List of valid vessel types.
        vessel_types = [
            explib.SEATTLECLEARINGHOUSE_VESSEL_TYPE_WAN,
            explib.SEATTLECLEARINGHOUSE_VESSEL_TYPE_LAN,
            explib.SEATTLECLEARINGHOUSE_VESSEL_TYPE_NAT,
            explib.SEATTLECLEARINGHOUSE_VESSEL_TYPE_RAND,
        ]

        if vessel_type not in vessel_types:
            raise ValueError(
                "Invalid vessel type specified. Argument 'vessel_type' must be one of "
                + "the SEATTLECLEARINGHOUSE_VESSEL_TYPE_* constants defined in 'experimentlib.py'"
            )

        self.config["vessel_type"] = vessel_type

        # If a program file isn't passed, assume user will handle the issue
        if program_filename:
            # Verify that program file exists
            if not os.path.isfile(program_filename):
                raise ValueError("Specified program file '" + program_filename + "' does not exist")

            self.config["program_filename"] = program_filename

        # Setup explib identity object and GENI details
        self.config["identity"] = explib.create_identity_from_key_files(
            geni_username + ".publickey", geni_username + ".privatekey"
        )
        self.config["geni_port"] = explib.seattlegeni_user_port(self.config["identity"])

        # Ensure that the user has enough credits to acquire the specified number of vessels.
        num_vessel_credits = explib.seattlegeni_max_vessels_allowed(self.config["identity"])

        if vessel_count > num_vessel_credits:
            raise ValueError(
                "Invalid number of vessels specified. The number of deployed vessels must "
                + "be less than or equal to the user's number of vessel credits."
            )

        self.config["vessel_count"] = vessel_count

        # Set up the logger according to passed arguments
        if log_filename:
            # Add the file logger.
            fileLog = logging.FileHandler(log_filename, "w")
            fileLog.setFormatter(logging.Formatter("%(asctime)s %(levelname)-8s %(message)s", "%Y-%m-%d %H:%M:%S"))
            self.logger.addHandler(fileLog)
        else:
            # Add the console logger.
            consoleLog = logging.StreamHandler()
            consoleLog.setFormatter(logging.Formatter("%(asctime)s %(levelname)-8s %(message)s", "%H:%M:%S"))
            self.logger.addHandler(consoleLog)

        # Setting the functions of 'run' to default
        self.init_overlord_func = default_init_overlord
        self.acquire_vessels_func = default_acquire_vessels
        self.init_vessels_func = default_initiate_vessels
        self.remove_vessels_func = default_remove_vessels
        self.maintenance_func = default_maintenance
def main():

    identity = experimentlib.create_identity_from_key_files(PUBLICKEY_FILENAME, PRIVATEKEY_FILENAME)

    # Get a list of nodes advertising under the public key. Some of these
    # nodes may be unreachable or may have gone offline since they advertised.
    # This won't try to communicate with the actual nodes.
    nodelocation_list = experimentlib.lookup_node_locations_by_identity(identity)

    print("nodelocation_list:" + str(nodelocation_list))

    # Talk to each advertising node to find out which vessels we have on each.
    # We get back a list of dictionaries, where each dictionary describes a
    # vessel. There may be multiple vessels from any single node in this list.
    active_vesselhandle_list = experimentlib.find_vessels_on_nodes(identity, nodelocation_list)

    print("active_vesselhandle_list:" + str(active_vesselhandle_list))

    # Now we want to find out which vessels we've acquired through seattlegeni
    # that are not in our list. We may, for example, want to release those
    # vessels because we consider them unusable.

    try:
        expected_vesselhandle_list = experimentlib.seattlegeni_get_acquired_vessels(identity)

        print("expected_vesselhandle_list:" + str(expected_vesselhandle_list))

        # If we already have enough usable vessels, we're done.
        if len(active_vesselhandle_list) >= MIN_VESSELS_TO_KEEP:
            print(
                "There are already "
                + str(len(active_vesselhandle_list))
                + " active vessels "
                + "and our MIN_VESSELS_TO_KEEP is "
                + str(MIN_VESSELS_TO_KEEP)
            )
            return

        # We assume all of our vessels come from seattlegeni, so if any vessels we
        # should have access to according to seattlegeni aren't accessible or
        # otherwise usable, then release them.
        vesselhandles_to_release = []
        for vesselhandle in expected_vesselhandle_list:
            if vesselhandle not in active_vesselhandle_list:
                vesselhandles_to_release.append(vesselhandle)

        if vesselhandles_to_release:
            print(
                str(len(vesselhandles_to_release))
                + " vessels were inaccessible, so will try to release them:"
                + str(vesselhandles_to_release)
            )
            try:
                experimentlib.seattlegeni_release_vessels(identity, vesselhandles_to_release)
            except experimentlib.SeattleClearinghouseError, e:
                print("Failed to release vessels: " + str(e))
            else:
                print("Vessels successfully released.")

        # Determine the maximum number of vessels we can acquire through seattlegeni.
        max_vessels_allowed = experimentlib.seattlegeni_max_vessels_allowed(identity)
        print("max_vessels_allowed: " + str(max_vessels_allowed))

        # Determine the number of vessels we already have acquired through seattlegeni.
        num_currently_acquired = len(experimentlib.seattlegeni_get_acquired_vessels(identity))
        print("currently_acquired_count: " + str(num_currently_acquired))

        # Let's try to get as close to MIN_VESSELS_TO_KEEP without requesting more
        # than is allowed by this account.
        num_vessels_to_request = min(max_vessels_allowed, MIN_VESSELS_TO_KEEP) - num_currently_acquired

        if num_vessels_to_request <= 0:
            print("This account doesn't have enough vessel credits to request more vessels.")
            return
        else:
            print("Will try to acquire " + str(num_vessels_to_request) + " vessels.")

        vessel_type = experimentlib.SEATTLECLEARINGHOUSE_VESSEL_TYPE_WAN
        acquired_vessels = experimentlib.seattlegeni_acquire_vessels(identity, vessel_type, num_vessels_to_request)

        print("Acquired " + str(num_vessels_to_request) + " vessels: " + str(acquired_vessels))
def main():

    identity = experimentlib.create_identity_from_key_files(
        PUBLICKEY_FILENAME, PRIVATEKEY_FILENAME)

    # Get a list of nodes advertising under the public key. Some of these
    # nodes may be unreachable or may have gone offline since they advertised.
    # This won't try to communicate with the actual nodes.
    nodelocation_list = experimentlib.lookup_node_locations_by_identity(
        identity)

    print("nodelocation_list:" + str(nodelocation_list))

    # Talk to each advertising node to find out which vessels we have on each.
    # We get back a list of dictionaries, where each dictionary describes a
    # vessel. There may be multiple vessels from any single node in this list.
    active_vesselhandle_list = experimentlib.find_vessels_on_nodes(
        identity, nodelocation_list)

    print("active_vesselhandle_list:" + str(active_vesselhandle_list))

    # Now we want to find out which vessels we've acquired through seattlegeni
    # that are not in our list. We may, for example, want to release those
    # vessels because we consider them unusable.

    try:
        expected_vesselhandle_list = experimentlib.seattlegeni_get_acquired_vessels(
            identity)

        print("expected_vesselhandle_list:" + str(expected_vesselhandle_list))

        # If we already have enough usable vessels, we're done.
        if len(active_vesselhandle_list) >= MIN_VESSELS_TO_KEEP:
            print("There are already " + str(len(active_vesselhandle_list)) +
                  " active vessels " + "and our MIN_VESSELS_TO_KEEP is " +
                  str(MIN_VESSELS_TO_KEEP))
            return

        # We assume all of our vessels come from seattlegeni, so if any vessels we
        # should have access to according to seattlegeni aren't accessible or
        # otherwise usable, then release them.
        vesselhandles_to_release = []
        for vesselhandle in expected_vesselhandle_list:
            if vesselhandle not in active_vesselhandle_list:
                vesselhandles_to_release.append(vesselhandle)

        if vesselhandles_to_release:
            print(
                str(len(vesselhandles_to_release)) +
                " vessels were inaccessible, so will try to release them:" +
                str(vesselhandles_to_release))
            try:
                experimentlib.seattlegeni_release_vessels(
                    identity, vesselhandles_to_release)
            except experimentlib.SeattleClearinghouseError, e:
                print("Failed to release vessels: " + str(e))
            else:
                print("Vessels successfully released.")

        # Determine the maximum number of vessels we can acquire through seattlegeni.
        max_vessels_allowed = experimentlib.seattlegeni_max_vessels_allowed(
            identity)
        print("max_vessels_allowed: " + str(max_vessels_allowed))

        # Determine the number of vessels we already have acquired through seattlegeni.
        num_currently_acquired = len(
            experimentlib.seattlegeni_get_acquired_vessels(identity))
        print("currently_acquired_count: " + str(num_currently_acquired))

        # Let's try to get as close to MIN_VESSELS_TO_KEEP without requesting more
        # than is allowed by this account.
        num_vessels_to_request = min(
            max_vessels_allowed, MIN_VESSELS_TO_KEEP) - num_currently_acquired

        if num_vessels_to_request <= 0:
            print(
                "This account doesn't have enough vessel credits to request more vessels."
            )
            return
        else:
            print("Will try to acquire " + str(num_vessels_to_request) +
                  " vessels.")

        vessel_type = experimentlib.SEATTLECLEARINGHOUSE_VESSEL_TYPE_WAN
        acquired_vessels = experimentlib.seattlegeni_acquire_vessels(
            identity, vessel_type, num_vessels_to_request)

        print("Acquired " + str(num_vessels_to_request) + " vessels: " +
              str(acquired_vessels))