def main(argv=None):
  ##############################################################################
  # Get a parser from omni that understands omni options
  ##############################################################################
  parser = omni.getParser()
  # update usage for help message
  omni_usage = parser.get_usage()
  parser.set_usage(omni_usage+"\naddMemberToSliceAndSlivers.py adds " + 
                   "the given member to the given slice and installs " +
                   "their SSH keys on all slivers known to the CH plus at all specified aggregates.\n " +
                   "Takes slice name and username as arguments")

  # options is an optparse.Values object, and args is a list
  options, args = omni.parse_args(sys.argv[1:], parser=parser)

  if len(args) < 2:
    print "Usage: addMemberToSliceAndSlivers.py <slicename> <username>"
    sys.exit(-1)

  sliceName = args[0]
  userName = args[1]
  omniargs = ['addslicemember', sliceName, userName]

  print "Calling Omni to add %s to slice %s\n" % (userName, sliceName)
  try:
    text, retItem = omni.call(omniargs, options)
    if not retItem:
      print "\nFailed to add member to slice: %s" % text
      sys.exit(-1)
  except OmniError, oe:
    print "\nOmni call failed: %s\n" % oe
    sys.exit(-1)
def main(argv=None):
    ##############################################################################
    # Get a parser from omni that understands omni options
    ##############################################################################
    parser = omni.getParser()
    # update usage for help message
    omni_usage = parser.get_usage()
    parser.set_usage(
        omni_usage + "\naddMemberToSliceAndSlivers.py adds " +
        "the given member to the given slice and installs " +
        "their SSH keys on all slivers known to the CH plus at all specified aggregates.\n "
        + "Takes slice name and username as arguments")

    # options is an optparse.Values object, and args is a list
    options, args = omni.parse_args(sys.argv[1:], parser=parser)

    if len(args) < 2:
        print "Usage: addMemberToSliceAndSlivers.py <slicename> <username>"
        sys.exit(-1)

    sliceName = args[0]
    userName = args[1]
    omniargs = ['addslicemember', sliceName, userName]

    print "Calling Omni to add %s to slice %s\n" % (userName, sliceName)
    try:
        text, retItem = omni.call(omniargs, options)
        if not retItem:
            print "\nFailed to add member to slice: %s" % text
            sys.exit(-1)
    except OmniError, oe:
        print "\nOmni call failed: %s\n" % oe
        sys.exit(-1)
Exemplo n.º 3
0
def main(argv=None):
  ##############################################################################
  # Get a parser from omni that understands omni options
  ##############################################################################
  parser = omni.getParser()
  # update usage for help message
  omni_usage = parser.get_usage()
  parser.set_usage(omni_usage+"\nrenewSliceAndSlivers.py renews the given slice and all slivers at aggregates known to the GENI CH for 60 days.\n " +
                   "Takes slice name as argument")

  # options is an optparse.Values object, and args is a list
  options, args = omni.parse_args(sys.argv[1:], parser=parser)

  sliceName = args[0]
  newDate = datetime.datetime.utcnow() + datetime.timedelta(days=60)
  # Strip fractional seconds from times to avoid errors at PG AMs
  newDate = newDate.replace(microsecond=0)
  retcode = 0

  for command in ['renewslice', 'renewsliver']:
    # Here we use --raise-error-on-v2-amapi-error. Note though that if 1 AM has a problem, the script stops. Is that what we want?
    # IE will all AMs return code 0 if they renew the slice alap?
    # Could supply arg '--warn' to turn down logging. But then we'd want this script to have Omni write to a log file.
    omniargs = ['--alap', '--useSliceAggregates', '--raise-error-on-v2-amapi-error', command, sliceName, "'%s'" % newDate.isoformat()]

    print "Calling Omni to renew slice %s%s until %sZ\n" % (sliceName, (" slivers" if command=="renewsliver" else ""), newDate.isoformat())
    try:
      text, retItem = omni.call(omniargs, options)
    except OmniError, oe:
      print "\n ***** Omni call failed: %s\n" % oe
      retcode = str(oe)
      continue
    print text
    print "\n"
Exemplo n.º 4
0
def main(argv=None):
    ##############################################################################
    # Get a parser from omni that understands omni options
    ##############################################################################
    parser = omni.getParser()
    # set usage for help message
    parser.set_usage(
        "renewSliceAndSlivers.py [-r projectname] <slicename>\n"
        + "renewSliceAndSlivers.py renews the given slice and all slivers at aggregates known to the GENI CH for 60 days.\n"
        + "Uses standard Omni config file and standard omni commandline options. Run 'omni -h' for details."
    )

    if len(sys.argv[1:]) == 0 or (len(sys.argv[1:]) == 1 and str(sys.argv[1]).lower() in ("-h", "-?", "--help")):
        parser.print_usage()
        return 0

    # options is an optparse.Values object, and args is a list
    options, args = omni.parse_args(sys.argv[1:], parser=parser)

    if not args or len(args) < 1:
        parser.print_usage()
        return 1

    sliceName = args[0]
    newDate = datetime.datetime.utcnow() + datetime.timedelta(days=60)
    # Strip fractional seconds from times to avoid errors at PG AMs
    newDate = newDate.replace(microsecond=0)
    retcode = 0

    for command in ["renewslice", "renewsliver"]:
        # Here we use --raise-error-on-v2-amapi-error. Note though that if 1 AM has a problem, the script stops. Is that what we want?
        # IE will all AMs return code 0 if they renew the slice alap?
        # Could supply arg '--warn' to turn down logging. But then we'd want this script to have Omni write to a log file.
        omniargs = [
            "--alap",
            "--useSliceAggregates",
            "--raise-error-on-v2-amapi-error",
            command,
            sliceName,
            "'%s'" % newDate.isoformat(),
        ]

        print "Calling Omni to renew slice %s%s until %sZ\n" % (
            sliceName,
            (" slivers" if command == "renewsliver" else ""),
            newDate.isoformat(),
        )
        try:
            text, retItem = omni.call(omniargs, options)
        except OmniError, oe:
            print "\n ***** Omni call failed: %s\n" % oe
            retcode = str(oe)
            continue
        print text
        print "\n"
Exemplo n.º 5
0
def main(argv=None):
    ##############################################################################
    # Get a parser from omni that understands omni options
    ##############################################################################
    parser = omni.getParser()
    parser.set_usage("%s [options] username" % sys.argv[0])
    options, args = omni.parse_args(sys.argv[1:], parser=parser)

    # pull username from the command line
    if len(args) > 0:
        username = args[0].strip()
    else:
        username = None


#    if not username:
#      sys.exit( "Must provide a username as the first argument of script" )

##############################################################################
# And now call omni, and omni sees your parsed options and arguments
# (1) Run equivalent of 'omni.py listmyslices username'
# (2) For each returned slicename run equivalent of:
#        'omni.py print_slice_expiration slicename'
##############################################################################
# (1) Run equivalent of 'omni.py listmyslices username'
    if username:
        text, sliceList = omni.call(['listmyslices', username], options)
    else:
        text, sliceList = omni.call(['listmyslices'], options)
        username = "******"

    #  print some summary info
    printStr = "=" * 80 + "\n"
    if len(sliceList) > 0:
        printStr += "User %s has %d slice(s):\n" % (username, len(sliceList))
    else:
        printStr += "User %s has NO slices\n" % (username)

    # (2) For each returned slicename run equivalent of:
    #        'omni.py print_slice_expiration slicename'

    for slicename in sliceList:
        omniargs = []
        omniargs.append('print_slice_expiration')
        omniargs.append(slicename)
        text, expiration = omni.call(omniargs, options)

        printStr += "%s\n" % (str(expiration))
    printStr += "=" * 80
    return printStr
def main(argv=None):
  ##############################################################################
  # Get a parser from omni that understands omni options
  ##############################################################################
  parser = omni.getParser()
  parser.set_usage("%s [options] username"%sys.argv[0])
  options, args = omni.parse_args(sys.argv[1:], parser=parser)

  # pull username from the command line
  if len(args) > 0:
    username = args[0].strip()
  else:
    username = None
#    if not username:
#      sys.exit( "Must provide a username as the first argument of script" )

  ##############################################################################
  # And now call omni, and omni sees your parsed options and arguments
  # (1) Run equivalent of 'omni.py listmyslices username'
  # (2) For each returned slicename run equivalent of: 
  #        'omni.py print_slice_expiration slicename'
  ##############################################################################
  # (1) Run equivalent of 'omni.py listmyslices username'
  if username:
    text, sliceList = omni.call( ['listmyslices', username], options )
  else:
    text, sliceList = omni.call( ['listmyslices'], options )
    username = "******"
  
  #  print some summary info
  printStr = "="*80+"\n"
  if len(sliceList)>0:
    printStr += "User %s has %d slice(s):\n"%(username, len(sliceList))
  else:
    printStr += "User %s has NO slices\n"%(username)

  # (2) For each returned slicename run equivalent of: 
  #        'omni.py print_slice_expiration slicename'
  
  for slicename in sliceList:
    omniargs = []
    omniargs.append('print_slice_expiration')
    omniargs.append(slicename)
    text, expiration = omni.call( omniargs, options )        

    printStr += "%s\n"%(str(expiration))
  printStr += "="*80            
  return printStr
Exemplo n.º 7
0
def main(argv=None):
    parser = omni.getParser()
    # Parse Options
    (options, args) = parser.parse_args()

    text, obj = omni.call(args, options)

    if type(obj) == type({}):
        obj2 = {}
        for key, value in obj.items():
            obj2[str(key)] = value
    else:
        obj2 = obj
    # serialize using json
    jsonObj = json.dumps((text, obj2), indent=4)
    print jsonObj
Exemplo n.º 8
0
def main(argv=None):
    parser = omni.getParser()
    # Parse Options
    (options, args) = parser.parse_args()

    text, obj = omni.call( args, options )

    if type(obj) == type({}):
        obj2 = {}
        for key, value in obj.items():
            obj2[str(key)]=value
    else:
        obj2 = obj
    # serialize using json
    jsonObj = json.dumps( (text, obj2), indent=4 )
    print jsonObj
Exemplo n.º 9
0
def getParser() : 
  parser = omni.getParser()

  usage = "\n\tTypically: \t%s slicename --useSliceAggregates" % os.path.basename(sys.argv[0]).split(".")[0]
  usage += "\n\nReports the status of nodes and the ssh command to login to them."
  usage += "\nTry the --no-keys and -o options."
  usage += "\nIn addition, takes the same options as omni (-c, -a, -V, etc)."
 
  usage += "\n\n== Providing a private key to ssh ==\nIn order to ssh, you will need to supply a private key.\nThere are three options for doing so:\n\t1) always append the -i option to the ssh command: \n\t\t$ ssh -i <path to private key> ...\n\t2) run an ssh agent and add your private key to that agent: \n\t\t$ ssh-add <path to private key>\n\t\t$ ssh ...\n\t3) create an ssh config file using the -o option:\n\t\t$ readyToLogin.py ... -o\n\t\tSSH Config saved at: .../sshconfig.txt\n\t\tLogin info saved at: .../logininfo.txt\n\t\t$ mv sshconfig.txt ~/.ssh/config\n"
  parser.set_usage(usage)
  
  # Parse Options
  parser.add_option("-x", "--xterm", dest="xterm",
                    action="store_true", 
                    default=False,
                    help="add xterm in the SSH commands")
  parser.add_option( "--readyonly", dest="readyonly",
                    action="store_true", 
                    default=False,
                    help="Only print nodes in ready state")
  parser.add_option( "--do-not-overwrite", dest="donotoverwrite",
                    action="store_true", 
                    default=False,
                    help="If '-o' is set do not overwrite files")

  parser.add_option("--no-keys", 
                    dest="include_keys",
                    help="Do not include ssh keys in output",
                    action="store_false", default=True)
  parser.add_option("--fallbackToStatusForPG",
                    dest="fallback_status_PG",
                    help="For ProtoGENI/InstaGENI nodes, fallback to querying login info from SliverStatus if it contains login info not found in the manifest.",
                    action="store_true", default=False)
  parser.add_option("--ansible-inventory",
                    dest="ansible_inventory",
                    help="Create an ansible inventory containing a single line for each host in your slice.",
                    action="store_true", default=False)
  parser.add_option("--ansible-username",
                    dest="ansible_username",
                    action="store", type="string", 
                    help="Specify the username to use in ansible.")
  parser.add_option("--no-ansible-username",
                    dest="no_ansible_username",
                    help="Never include the username to use in the ansible inventory file.",
                    action="store_true", default=False)
  return parser
Exemplo n.º 10
0
def getParser() : 
  parser = omni.getParser()

  usage = "\n\tTypically: \t%s slicename --useSliceAggregates" % os.path.basename(sys.argv[0]).split(".")[0]
  usage += "\n\nReports the status of nodes and the ssh command to login to them."
  usage += "\nTry the --no-keys and -o options."
  usage += "\nIn addition, takes the same options as omni (-c, -a, -V, etc)."
 
  usage += "\n\n== Providing a private key to ssh ==\nIn order to ssh, you will need to supply a private key.\nThere are three options for doing so:\n\t1) always append the -i option to the ssh command: \n\t\t$ ssh -i <path to private key> ...\n\t2) run an ssh agent and add your private key to that agent: \n\t\t$ ssh-add <path to private key>\n\t\t$ ssh ...\n\t3) create an ssh config file using the -o option:\n\t\t$ readyToLogin.py ... -o\n\t\tSSH Config saved at: .../sshconfig.txt\n\t\tLogin info saved at: .../logininfo.txt\n\t\t$ mv sshconfig.txt ~/.ssh/config\n"
  parser.set_usage(usage)
  
  # Parse Options
  parser.add_option("-x", "--xterm", dest="xterm",
                    action="store_true", 
                    default=False,
                    help="add xterm in the SSH commands")
  parser.add_option( "--readyonly", dest="readyonly",
                    action="store_true", 
                    default=False,
                    help="Only print nodes in ready state")
  parser.add_option( "--do-not-overwrite", dest="donotoverwrite",
                    action="store_true", 
                    default=False,
                    help="If '-o' is set do not overwrite files")

  parser.add_option("--no-keys", 
                    dest="include_keys",
                    help="Do not include ssh keys in output",
                    action="store_false", default=True)
  parser.add_option("--fallbackToStatusForPG",
                    dest="fallback_status_PG",
                    help="For ProtoGENI/InstaGENI nodes, fallback to querying login info from SliverStatus if it contains login info not found in the manifest.",
                    action="store_true", default=False)
  parser.add_option("--ansible-inventory",
                    dest="ansible_inventory",
                    help="Create an ansible inventory containing a single line for each host in your slice.",
                    action="store_true", default=False)
  parser.add_option("--ansible-username",
                    dest="ansible_username",
                    action="store", type="string", 
                    help="Specify the username to use in ansible.")
  parser.add_option("--no-ansible-username",
                    dest="no_ansible_username",
                    help="Never include the username to use in the ansible inventory file.",
                    action="store_true", default=False)
  return parser
Exemplo n.º 11
0
def main(argv=None):
    ##############################################################################
    # Get a parser from omni that understands omni options
    ##############################################################################
    parser = omni.getParser()
    # update usage for help message
    omni_usage = parser.get_usage()
    parser.set_usage(
        omni_usage +
        "\nrenewSliceAndSlivers.py renews the given slice and all slivers at aggregates known to the GENI CH for 60 days.\n "
        + "Takes slice name as argument")

    # options is an optparse.Values object, and args is a list
    options, args = omni.parse_args(sys.argv[1:], parser=parser)

    sliceName = args[0]
    newDate = datetime.datetime.utcnow() + datetime.timedelta(days=60)
    # Strip fractional seconds from times to avoid errors at PG AMs
    newDate = newDate.replace(microsecond=0)
    retcode = 0

    for command in ['renewslice', 'renewsliver']:
        # Here we use --raise-error-on-v2-amapi-error. Note though that if 1 AM has a problem, the script stops. Is that what we want?
        # IE will all AMs return code 0 if they renew the slice alap?
        # Could supply arg '--warn' to turn down logging. But then we'd want this script to have Omni write to a log file.
        omniargs = [
            '--alap', '--useSliceAggregates',
            '--raise-error-on-v2-amapi-error', command, sliceName,
            "'%s'" % newDate.isoformat()
        ]

        print "Calling Omni to renew slice %s%s until %sZ\n" % (
            sliceName, (" slivers" if command == "renewsliver" else ""),
            newDate.isoformat())
        try:
            text, retItem = omni.call(omniargs, options)
        except OmniError, oe:
            print "\n ***** Omni call failed: %s\n" % oe
            retcode = str(oe)
            continue
        print text
        print "\n"
Exemplo n.º 12
0
def call(argv, options=None):

    if options is not None and not options.__class__==optparse.Values:
        raise OmniError("Invalid options argument to call: must be an optparse.Values object")

    if argv is None or not type(argv) == list:
        raise OmniError("Invalid argv argument to call: must be a list")

    ##############################################################################
    # Get a parser from omni that understands omni options
    ##############################################################################
    parser = omni.getParser()
    # update usage for help message
    omni_usage = parser.get_usage()
    parser.set_usage("\n" + "GENI Omni Stitching Tool\n" + "Copyright (c) 2013-2015 Raytheon BBN Technologies\n" + 
                     omni_usage+
                     "\nstitcher.py reserves multi-aggregate fully bound topologies, including stitching, if the call is createsliver or allocate; else it just calls Omni.\n")

   ##############################################################################
    # Add additional optparse.OptionParser style options
    # Be sure not to re-use options already in use by omni for
    # different meanings, otherwise you'll raise an OptionConflictError
    ##############################################################################
    parser.add_option("--defaultCapacity", default=DEFAULT_CAPACITY,
                      type="int", help="Default stitched link capacity in Kbps - default is 20000 meaning ~20Mbps")
    parser.add_option("--excludehop", metavar="HOP_EXCLUDE", action="append",
                      help="Hop URN to exclude from any path")
    parser.add_option("--includehop", metavar="HOP_INCLUDE", action="append",
                      help="Hop URN to include on every path - use with caution")
    parser.add_option("--includehoponpath", metavar="HOP_INCLUDE PATH", action="append", nargs=2,
                      help="Hop URN to include and then path (link client_id) to include it on")
    parser.add_option("--fixedEndpoint", default=False, action="store_true",
                      help="RSpec uses a static endpoint - add a fake node with an interface on every link")
    parser.add_option("--noExoSM", default=False, action="store_true",
                      help="Always use local ExoGENI racks, not the ExoSM, where possible (default %default)")
    parser.add_option("--useExoSM", default=False, action="store_true",
                      help="Always use the ExoGENI ExoSM, not the individual EG racks, where possible (default %default)")
    parser.add_option("--fileDir", default=None,
                      help="Directory for all output files generated. By default some files go in /tmp, some in the CWD, some in ~/.gcf.")
    parser.add_option("--logFileCount", default=5, type="int",
                      help="Number of backup log files to keep, Default %default")
    parser.add_option("--ionRetryIntervalSecs", type="int", 
                      help="Seconds to sleep before retrying at DCN aggregates (default: %default)",
                      default=gcf.omnilib.stitch.objects.DCN_AM_RETRY_INTERVAL_SECS)
    parser.add_option("--ionStatusIntervalSecs", type="int", 
                      help="Seconds to sleep between sliverstatus calls at DCN aggregates (default %default)",
                      default=30)
    parser.add_option("--noReservation", default=False, action="store_true",
                      help="Do no reservations: just generate the expanded request RSpec (default %default)")
    parser.add_option("--scsURL",
                      help="URL to the SCS service. Default: Value of 'scs_url' in omni_config or " + SCS_URL,
                      default=None)
    parser.add_option("--timeout", default=0, type="int",
                      help="Max minutes to allow stitcher to run before killing a reservation attempt (default %default minutes, 0 means no timeout).")
    parser.add_option("--noAvailCheck", default=False, action="store_true",
                      help="Disable checking current VLAN availability where possible.")
    parser.add_option("--genRequest", default=False, action="store_true",
                      help="Generate and save an expanded request RSpec, but do no reservation.")
    parser.add_option("--noDeleteAtEnd", default=False, action="store_true",
                      help="On failure or Ctrl-C do not delete any reservations completed at some aggregates (default %default).")
    parser.add_option("--noTransitAMs", default=False, action="store_true",
                      help="Do not reserve resources at intermediate / transit aggregates; allow experimenter to manually complete the circuit (default %default).")
    parser.add_option("--noSCS", default=False, action="store_true",
                      help="Do not call the SCS to expand or add a stitching extension. Use this only if supplying any needed stitching extension and the SCS would fail your request. (default %default).")
    parser.add_option("--fakeModeDir",
                      help="Developers only: If supplied, use canned server responses from this directory",
                      default=None)
    parser.add_option("--savedSCSResults", default=None,
                      help="Developers only: Use this saved file of SCS results instead of calling SCS (saved previously using --debug)")
    parser.add_option("--useSCSSugg", default=False, action="store_true",
                      help="Developers only: Always use the VLAN tags the SCS suggests, not 'any'.")
    parser.add_option("--noEGStitching", default=False, action="store_true",
                      help="Developers only: Use GENI stitching, not ExoGENI stitching.")
    parser.add_option("--noEGStitchingOnLink", metavar="LINK_ID", action="append",
                      help="Developers only: Use GENI stitching on this particular link only, not ExoGENI stitching.")
    #  parser.add_option("--script",
    #                    help="If supplied, a script is calling this",
    #                    action="store_true", default=False)

    # Put our logs in a different file by default
    parser.set_defaults(logoutput='stitcher.log')

    # Configure stitcher with a specific set of configs by default

    # First, set the default logging config file
    lcfile = os.path.join(sys.path[0], os.path.join("gcf","stitcher_logging.conf"))

    # Windows & Mac binaries do not get the .conf file in the proper archive apparently
    # And even if they did, it appears the logging stuff can't readily read .conf files
    # from that archive.
    # Solution 1 that fails (no pkg_resources on windows so far, needs the file in the .zip)
    #    lcfile = pkg_resources.resource_filename("gcf", "stitcher_logging.conf")
    # Solution2 is to use pkgutil to read the file from the archive
    # And write it to a temp file that the logging stuff can use.
    # Note this requires finding some way to get the file into the archive
    # With whatever I do, I want to read the file direct from source per above if possible

    if not os.path.exists(lcfile):
        # File didn't exist as a regular file among python source
        # Try it where py2exe (Windows) puts resources (one directory up, parallel to zip). 
        lcfile = os.path.join(os.path.normpath(os.path.join(sys.path[0], '..')), os.path.join("gcf","stitcher_logging.conf"))

    if not os.path.exists(lcfile):
        # File didn't exist in dir parallel to zip of source
        # Try one more up, but no gcf sub-directory - where py2app (Mac) puts it.
        lcfile = os.path.join(os.path.normpath(os.path.join(os.path.join(sys.path[0], '..'), '..')), "stitcher_logging.conf")

    if not os.path.exists(lcfile):
        # Now we'll try a couple approaches to read the .conf file out of a source zip
        # And put it in a temp directory
        tmpdir = os.path.normpath(os.getenv("TMPDIR", os.getenv("TMP", "/tmp")))
        if tmpdir and tmpdir != "" and not os.path.exists(tmpdir):
            os.makedirs(tmpdir)
        lcfile = os.path.join(tmpdir, "stitcher_logging.conf")

        try:
            # This approach requires the .conf be in the source.zip (e.g. library.zip, python27.zip)
            # On Windows (py2exe) this isn't easy apparently. But it happens by default on Mac (py2app)
            # Note that could be a manual copy & paste possibly
            import pkgutil
            lconf = pkgutil.get_data("gcf", "stitcher_logging.conf")
            with open(lcfile, 'w') as file:
                file.write(lconf)
            #print "Read config with pkgutils %s" % lcfile
        except Exception, e:
            #print "Failed to read .conf file using pkgutil: %s" % e
            # If we didn't get the file in the archive, use the .py version
            # I find this solution distasteful
            from gcf import stitcher_logging_deft
            try:
                with open(lcfile, 'w') as file:
                    file.write(stitcher_logging_deft.DEFT_STITCHER_LOGGING_CONFIG)
            except Exception, e2:
                sys.exit("Error configuring logging: Could not write (from python default) logging config file %s: %s" % (lcfile, e2))
Exemplo n.º 13
0
def call(argv, options=None):

    if options is not None and not options.__class__ == optparse.Values:
        raise OmniError(
            "Invalid options argument to call: must be an optparse.Values object"
        )

    if argv is None or not type(argv) == list:
        raise OmniError("Invalid argv argument to call: must be a list")

    ##############################################################################
    # Get a parser from omni that understands omni options
    ##############################################################################
    parser = omni.getParser()
    # update usage for help message
    omni_usage = parser.get_usage()
    parser.set_usage(
        "\n" + "GENI Omni Stitching Tool\n" +
        "Copyright (c) 2013-2015 Raytheon BBN Technologies\n" + omni_usage +
        "\nstitcher.py reserves multi-aggregate fully bound topologies, including stitching, if the call is createsliver or allocate; else it just calls Omni.\n"
    )

    ##############################################################################
    # Add additional optparse.OptionParser style options
    # Be sure not to re-use options already in use by omni for
    # different meanings, otherwise you'll raise an OptionConflictError
    ##############################################################################
    parser.add_option(
        "--defaultCapacity",
        default=DEFAULT_CAPACITY,
        type="int",
        help=
        "Default stitched link capacity in Kbps - default is 20000 meaning ~20Mbps"
    )
    parser.add_option("--excludehop",
                      metavar="HOP_EXCLUDE",
                      action="append",
                      help="Hop URN to exclude from any path")
    parser.add_option(
        "--includehop",
        metavar="HOP_INCLUDE",
        action="append",
        help="Hop URN to include on every path - use with caution")
    parser.add_option(
        "--includehoponpath",
        metavar="HOP_INCLUDE PATH",
        action="append",
        nargs=2,
        help=
        "Hop URN to include and then path (link client_id) to include it on")
    parser.add_option(
        "--fixedEndpoint",
        default=False,
        action="store_true",
        help=
        "RSpec uses a static endpoint - add a fake node with an interface on every link"
    )
    parser.add_option(
        "--noExoSM",
        default=False,
        action="store_true",
        help=
        "Always use local ExoGENI racks, not the ExoSM, where possible (default %default)"
    )
    parser.add_option(
        "--useExoSM",
        default=False,
        action="store_true",
        help=
        "Always use the ExoGENI ExoSM, not the individual EG racks, where possible (default %default)"
    )
    parser.add_option(
        "--fileDir",
        default=None,
        help=
        "Directory for all output files generated. By default some files go in /tmp, some in the CWD, some in ~/.gcf."
    )
    parser.add_option(
        "--logFileCount",
        default=5,
        type="int",
        help="Number of backup log files to keep, Default %default")
    parser.add_option(
        "--ionRetryIntervalSecs",
        type="int",
        help=
        "Seconds to sleep before retrying at DCN aggregates (default: %default)",
        default=gcf.omnilib.stitch.objects.DCN_AM_RETRY_INTERVAL_SECS)
    parser.add_option(
        "--ionStatusIntervalSecs",
        type="int",
        help=
        "Seconds to sleep between sliverstatus calls at DCN aggregates (default %default)",
        default=30)
    parser.add_option(
        "--noReservation",
        default=False,
        action="store_true",
        help=
        "Do no reservations: just generate the expanded request RSpec (default %default)"
    )
    parser.add_option(
        "--scsURL",
        help=
        "URL to the SCS service. Default: Value of 'scs_url' in omni_config or "
        + SCS_URL,
        default=None)
    parser.add_option(
        "--timeout",
        default=0,
        type="int",
        help=
        "Max minutes to allow stitcher to run before killing a reservation attempt (default %default minutes, 0 means no timeout)."
    )
    parser.add_option(
        "--noAvailCheck",
        default=False,
        action="store_true",
        help="Disable checking current VLAN availability where possible.")
    parser.add_option(
        "--genRequest",
        default=False,
        action="store_true",
        help=
        "Generate and save an expanded request RSpec, but do no reservation.")
    parser.add_option(
        "--noDeleteAtEnd",
        default=False,
        action="store_true",
        help=
        "On failure or Ctrl-C do not delete any reservations completed at some aggregates (default %default)."
    )
    parser.add_option(
        "--noTransitAMs",
        default=False,
        action="store_true",
        help=
        "Do not reserve resources at intermediate / transit aggregates; allow experimenter to manually complete the circuit (default %default)."
    )
    parser.add_option(
        "--fakeModeDir",
        help=
        "Developers only: If supplied, use canned server responses from this directory",
        default=None)
    parser.add_option(
        "--savedSCSResults",
        default=None,
        help=
        "Developers only: Use this saved file of SCS results instead of calling SCS (saved previously using --debug)"
    )
    parser.add_option(
        "--useSCSSugg",
        default=False,
        action="store_true",
        help=
        "Developers only: Always use the VLAN tags the SCS suggests, not 'any'."
    )
    parser.add_option(
        "--noEGStitching",
        default=False,
        action="store_true",
        help="Developers only: Use GENI stitching, not ExoGENI stitching.")
    parser.add_option(
        "--noEGStitchingOnLink",
        metavar="LINK_ID",
        action="append",
        help=
        "Developers only: Use GENI stitching on this particular link only, not ExoGENI stitching."
    )
    #  parser.add_option("--script",
    #                    help="If supplied, a script is calling this",
    #                    action="store_true", default=False)

    # Put our logs in a different file by default
    parser.set_defaults(logoutput='stitcher.log')

    # Configure stitcher with a specific set of configs by default

    # First, set the default logging config file
    lcfile = os.path.join(sys.path[0],
                          os.path.join("gcf", "stitcher_logging.conf"))

    # Windows & Mac binaries do not get the .conf file in the proper archive apparently
    # And even if they did, it appears the logging stuff can't readily read .conf files
    # from that archive.
    # Solution 1 that fails (no pkg_resources on windows so far, needs the file in the .zip)
    #    lcfile = pkg_resources.resource_filename("gcf", "stitcher_logging.conf")
    # Solution2 is to use pkgutil to read the file from the archive
    # And write it to a temp file that the logging stuff can use.
    # Note this requires finding some way to get the file into the archive
    # With whatever I do, I want to read the file direct from source per above if possible

    if not os.path.exists(lcfile):
        # File didn't exist as a regular file among python source
        # Try it where py2exe (Windows) puts resources (one directory up, parallel to zip).
        lcfile = os.path.join(
            os.path.normpath(os.path.join(sys.path[0], '..')),
            os.path.join("gcf", "stitcher_logging.conf"))

    if not os.path.exists(lcfile):
        # File didn't exist in dir parallel to zip of source
        # Try one more up, but no gcf sub-directory - where py2app (Mac) puts it.
        lcfile = os.path.join(
            os.path.normpath(
                os.path.join(os.path.join(sys.path[0], '..'), '..')),
            "stitcher_logging.conf")

    if not os.path.exists(lcfile):
        # Now we'll try a couple approaches to read the .conf file out of a source zip
        # And put it in a temp directory
        tmpdir = os.path.normpath(os.getenv("TMPDIR", os.getenv("TMP",
                                                                "/tmp")))
        if tmpdir and tmpdir != "" and not os.path.exists(tmpdir):
            os.makedirs(tmpdir)
        lcfile = os.path.join(tmpdir, "stitcher_logging.conf")

        try:
            # This approach requires the .conf be in the source.zip (e.g. library.zip, python27.zip)
            # On Windows (py2exe) this isn't easy apparently. But it happens by default on Mac (py2app)
            # Note that could be a manual copy & paste possibly
            import pkgutil
            lconf = pkgutil.get_data("gcf", "stitcher_logging.conf")
            with open(lcfile, 'w') as file:
                file.write(lconf)
            #print "Read config with pkgutils %s" % lcfile
        except Exception, e:
            #print "Failed to read .conf file using pkgutil: %s" % e
            # If we didn't get the file in the archive, use the .py version
            # I find this solution distasteful
            from gcf import stitcher_logging_deft
            try:
                with open(lcfile, 'w') as file:
                    file.write(
                        stitcher_logging_deft.DEFT_STITCHER_LOGGING_CONFIG)
            except Exception, e2:
                sys.exit(
                    "Error configuring logging: Could not write (from python default) logging config file %s: %s"
                    % (lcfile, e2))
Exemplo n.º 14
0
def main(argv=None):
  ##############################################################################
  # Get a parser from omni that understands omni options
  ##############################################################################
  parser = omni.getParser()
  # update usage for help message
  omni_usage = parser.get_usage()
  parser.set_usage(omni_usage+"\nmyscript.py supports additional commands.\n\n\tCommands and their arguments are:\n\t\t\t[add stuff here]")

  ##############################################################################
  # Add additional optparse.OptionParser style options for your
  # script as needed.
  # Be sure not to re-use options already in use by omni for
  # different meanings, otherwise you'll raise an OptionConflictError
  ##############################################################################
  parser.add_option("--myScriptPrivateOption",
                    help="A non-omni option added by %s"%sys.argv[0],
                    action="store_true", default=False)
  # options is an optparse.Values object, and args is a list
  options, args = omni.parse_args(sys.argv[1:], parser=parser)
  if options.myScriptPrivateOption:
    # do something special for your private script's options
    print "Got myScriptOption"



  ##############################################################################
  # Try to read 2nd argument as an RSpec filename. Pull the AM URL and
  # and maybe slice name from that file.
  # Then construct omni args appropriately: command, slicename, action or rspecfile or datetime
  ##############################################################################
  omniargs = []
  if args and len(args)>1:
    sliceurn = None
    # Try to read args[1] as an RSpec filename to read
    rspecfile = args[1]
    rspec = None
    if rspecfile:
      print "Looking for slice name and AM URL in RSpec file %s" % rspecfile
      try:
        rspec = readFile(rspecfile)
      except:
        print "Failed to read rspec from '%s'. Not an RSpec? Will try to get AM/slice from args." % rspecfile

    if rspec:
    # Now parse the comments, whch look like this:
#<!-- Resources at AM:
#	URN: unspecified_AM_URN
#	URL: https://localhost:8001
# -->
# Reserved resources for:\n\tSlice: %s
# at AM:\n\tURN: %s\n\tURL: %s

      if not ("Resources at AM" in rspec or "Reserved resources for" in rspec):
        sys.exit("Could not find slice name or AM URL in RSpec '%s'" % rspec)
      amurn = None
      amurl = None
      # Pull out the AM URN and URL
      match = re.search(r"at AM:\n\tURN: (\S+)\n\tURL: (\S+)\n", rspec)
      if match:
        amurn = match.group(1)
        amurl = match.group(2)
        print "  Found AM %s (%s)" % (amurn, amurl)
        omniargs.append("-a")
        omniargs.append(amurl)

      # Pull out the slice name or URN if any
      if "Reserved resources for" in rspec:
        match = re.search(r"Reserved resources for:\n\tSlice: (\S+)\n\t", rspec)
        if match:
          sliceurn = match.group(1)
          print "  Found slice %s" % sliceurn

    command = args[0]
    rest = []
    if len(args) > 2:
      rest = args[2:]

    # If the command requires a slice and we didn't get a readable rspec from the rspecfile,
    # Then treat that as the slice
    if not sliceurn and rspecfile and not rspec:
      sliceurn = rspecfile
      rspecfile = None

    # construct the args in order
    omniargs.append(command)
    if sliceurn:
      omniargs.append(sliceurn)
    if rspecfile and command.lower() in ('createsliver', 'allocate'):
      omniargs.append(rspecfile)
    for arg in rest:
      omniargs.append(arg)
  elif len(args) == 1:
    omniargs = args
  else:
    print "Got no command or rspecfile. Run '%s -h' for more information."%sys.argv[0]
    return

  ##############################################################################
  # And now call omni, and omni sees your parsed options and arguments
  ##############################################################################
  print "Call Omni with args %s:\n" % omniargs
  try:
    text, retItem = omni.call(omniargs, options)
  except OmniError, oe:
    sys.exit("\nOmni call failed: %s" % oe)