Commit 3bbd843b authored by David Johnson's avatar David Johnson

Several things in this commit:

  * Prior to this commit, libplab depended on db state to create slivers
    and slices.  Now it can be done using the regular command line tools
    without the metadata in the db.  This makes development and debugging
    much easier and allows us to use the command-line tools even if state has
    been cleared out of the db (i.e., for sliver garbage collection).
  * Add support for sliver start/stop/restart via the v4 NM.
  * Some support for sliver garbage collection.
  * Various other improvements and cleanup.
parent 4a50330d
This diff is collapsed.
......@@ -306,9 +306,9 @@ class NMagent_wrapper:
arg = ticketdata
pass
# if NM4agent, try delivering the ticket first, to maximize our
# chances:
if self.__agent.__class__ == NM4agent:
# If the agent wants to deliver a ticket explicitly before the create
# call, we do that.
if self.__agent.__class__.__dict__.has_key('deliver_ticket'):
try:
res = tryXmlrpcCmd(self.__agent.deliver_ticket,ticketdata)
if res[0] == 0:
......@@ -355,6 +355,21 @@ class NMagent_wrapper:
else:
return tryXmlrpcCmd(self.__agent.create_sliver,ticketdata)
return None
def stop_sliver(self,slicename):
if self.__agent.__class__.__dict__.has_key('stop_sliver'):
return tryXmlrpcCmd(self.__agent.stop_sliver,slicename)
return 0
def start_sliver(self,slicename):
if self.__agent.__class__.__dict__.has_key('start_sliver'):
return tryXmlrpcCmd(self.__agent.start_sliver,slicename)
return 0
def restart_sliver(self,slicename):
if self.__agent.__class__.__dict__.has_key('restart_sliver'):
return tryXmlrpcCmd(self.__agent.restart_sliver,slicename)
return 0
pass
......@@ -421,7 +436,6 @@ class PLCagent:
return self.__server.UpdateSlice(self.__auth, self.__slicename,
{ 'expires' : expdate })
# XXX: this should work ok if xmlrpc converts lists to arrays...
def SliceNodesAdd(self,nodelist):
if not type(nodelist) == list:
nodelist = [nodelist]
......@@ -562,6 +576,7 @@ class mod_PLC4:
now = calendar.timegm(time.gmtime())
try:
# XXX: fix to take desc and url args! (i.e., SliceUpdate)
res = tryXmlrpcCmd(agent.SliceCreate)
if debug:
print "SliceCreate result: %s" % res
......@@ -572,8 +587,16 @@ class mod_PLC4:
raise
try:
userlist = slice.getSliceUsers()
# XXX: we might not always want to add emulabman
if userlist == None:
userlist = []
pass
if not EMULABMAN_EMAIL in userlist:
userlist.append(EMULABMAN_EMAIL)
pass
res = tryXmlrpcCmd(agent.SliceUsersAdd,
EMULABMAN_EMAIL)
userlist)
if debug:
print "SliceUsersAdd result: %s" % res
pass
......@@ -587,9 +610,11 @@ class mod_PLC4:
# that the slice doesn't include the local NM's node... or something
# like that... so we must add the nodes to the slice.
try:
# XXX: test hack
#nodelist = ['pcwf3.emulab.net']
nodelist = map(lambda x: x[2], slice.getSliceNodes())
tnodelist = slice.getSliceNodes()
if tnodelist == None:
tnodelist = []
pass
nodelist = map(lambda x: x[2], tnodelist)
res = tryXmlrpcCmd(agent.SliceNodesAdd, nodelist)
if debug:
print "SliceNodesAdd result: %s" % res
......@@ -756,7 +781,6 @@ class mod_PLC4:
raise
return cPickle.dumps(retval)
# XXX: fix to use new NM
def createNode(self, node):
plcagent = self.__getAgent(node.slice.slicename)
......@@ -820,7 +844,7 @@ class mod_PLC4:
try:
rcap = cPickle.loads(node.nodemeta)
except:
print "WARNING: couldn't load rcap"
#print "WARNING: couldn't load rcap"
pass
node.nmagent = NMagent_wrapper(node.IP,node.nodeid)
res = None
......@@ -840,18 +864,39 @@ class mod_PLC4:
return res
# XXX: MIGHT need fixing...
def renewNode(self, node, length = 0):
return self.createNode(node)
# XXX: add, now that the NM can do this...
def startNode(self,node):
return None
node.nmagent = NMagent_wrapper(node.IP,node.nodeid)
try:
res = node.nmagent.start_sliver(node.slice.slicename)
except:
print "Failed to start node %s/%s from slice %s" % \
(node.nodeid,node.IP,node.slice.slicename)
raise
return res
# XXX: add, now that the NM can do this...
def stopNode(self,node):
return None
node.nmagent = NMagent_wrapper(node.IP,node.nodeid)
try:
res = node.nmagent.stop_sliver(node.slice.slicename)
except:
print "Failed to stop node %s/%s from slice %s" % \
(node.nodeid,node.IP,node.slice.slicename)
raise
return res
def restartNode(self,node):
node.nmagent = NMagent_wrapper(node.IP,node.nodeid)
try:
res = node.nmagent.restart_sliver(node.slice.slicename)
except:
print "Failed to stop node %s/%s from slice %s" % \
(node.nodeid,node.IP,node.slice.slicename)
raise
return res
# XXX: this is broken, appears to be bug in GetSlices xmlrpc call in PLC4
def getSliceExpTime(self, slicename):
"""
......
......@@ -20,7 +20,10 @@ import libplab
def usage(me):
print "Usage: %s [ -vdf ] { alloc | renew | free } pid eid nodeid" % me
print "Usage: %s [-vdfE] {alloc|renew|free|stop|start|restart} pid eid nodeid\n" \
" Without Emulab DB:\n" \
" %s [-vdfE] {alloc|renew|free|stop|start|restart} slicename nodeid" \
% (me,me)
sys.exit(1)
def processException(command, nodeid, e):
......@@ -46,18 +49,32 @@ def main(args):
parser.add_option("--noIS", dest="noIS", action="store_true",
default=False,
help="Don't run InstantiateSliver() in mod_PLC")
parser.add_option("-E","--no-emulabify",dest="no_emulabify",default=False,
action="store_true",help="Do not install/config Emulab" \
" software on the node")
# parse command line options
opts, args = parser.parse_args(args[1:])
slicename = None
# make sure we were told what to do on the command line.
if not len(args) == 4:
if len(args) == 3:
command, slicename, nodeid = args
pass
elif len(args) == 4:
command, pid, eid, nodeid = args
pass
else:
usage(me)
pass
command, pid, eid, nodeid = args
plab = libplab.Plab()
slice = plab.loadSlice(pid, eid)
if slicename != None:
slice = plab.loadSliceNoDB(slicename)
pass
else:
slice = plab.loadSlice(pid, eid)
pass
if command == "alloc":
try:
......@@ -65,8 +82,10 @@ def main(args):
# With the v4 NM, we have to sleep a couple seconds to give
# the slice the a chance to get keys/acct stuff straightened out
# so we can actually slogin and copy fixsudo.sh to the node.
time.sleep(2)
node.emulabify()
if not opts.no_emulabify:
time.sleep(2)
node.emulabify()
pass
# Note that vnode_setup boots the node
pass
except Exception, e:
......@@ -99,6 +118,50 @@ def main(args):
pass
pass
elif command == "stop":
try:
node = slice.loadNode(nodeid)
node.stop()
pass
except Exception, e:
processException(command, nodeid, e)
sys.exit(1)
pass
pass
elif command == "start":
try:
node = slice.loadNode(nodeid)
node.start()
pass
except Exception, e:
processException(command, nodeid, e)
sys.exit(1)
pass
pass
elif command == "stop":
try:
node = slice.loadNode(nodeid)
node.stop()
pass
except Exception, e:
processException(command, nodeid, e)
sys.exit(1)
pass
pass
elif command == "restart":
try:
node = slice.loadNode(nodeid)
node.restart()
pass
except Exception, e:
processException(command, nodeid, e)
sys.exit(1)
pass
pass
else:
usage(me)
pass
......
......@@ -12,26 +12,73 @@ import getopt
from libtestbed import *
import libplab
usage = "%prog [ -vd ] { create | destroy } pid eid"
usage = "%prog [-vd] {create|destroy} pid eid\n" \
" Without Emulab DB:\n" \
"%prog [-vd] [-u <user1,...>] [-n <node1,...>] -c <slicedesc> \\\n" \
" {create|destroy} slicename"
# [-w <url>]
def main(args):
me = args[0]
parser = TBParser(usage)
parser.add_option("-u","--users",dest="users",action="store",
help="Comma-separated list of users to add to the slice",
default=None)
parser.add_option("-n","--nodes",dest="nodes",action="store",
help="Comma-separated list of hostnames to add to " \
"the slice",default=None)
parser.add_option("-c","--slicedesc",dest="slicedesc",action="store",
help="Slice description",default=None)
# parser.add_option("-w","--sliceurl",dest="sliceurl",action="store_true",
# help="Slice URL",default=None)
userlist,nodelist = None,None
(opts, args) = parser.parse_args()
if len(args) < 3:
usedb = True
if len(args) == 2:
usedb = False
command,slicename = args
if args[0] == 'create' and (opts.slicedesc == None \
or opts.slicedesc == ''):
parser.error("Must supply a slice description if creating by slicename!")
pass
if opts.nodes != None:
nodelist = opts.nodes.split(',')
pass
if opts.users != None:
userlist = opts.nodes.split(',')
pass
pass
elif len(args) == 3:
command,pid,eid = args
pass
else:
parser.error("Incorrect number of arguments")
command,pid,eid = args
pass
plab = libplab.Plab()
if command == "create":
slice = plab.createSlice(pid, eid)
if usedb:
slice = plab.createSlice(pid, eid)
pass
else:
slice = plab.createSliceNoDB(slicename,opts.slicedesc,
userlist=userlist,nodelist=nodelist)
pass
pass
elif command == "destroy":
slice = plab.loadSlice(pid, eid)
if usedb:
slice = plab.loadSlice(pid, eid)
pass
else:
slice = plab.loadSliceNoDB(slicename)
pass
slice.destroy()
pass
else:
usage(me)
pass
if __name__ == "__main__":
main(sys.argv)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment