From e6e30d8c8f72b904b34e93d2b9c4aef39b965b59 Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Thu, 28 Jan 2010 17:16:11 -0500 Subject: add the part-handler plugin If a part of a multipart file is 'text/part-handler' then it is expected to be python code that implements 2 methods - list_types() list the types that this part-handler supports, return a list. ie: return(['text/plain']) - handle_parts(data,ctype,filename,payload) this method will be called: once, when loaded, with ctype == '__begin__' once per part once, at the end, with ctype == '__end__' - ctype is the content type ('text/plain') - filename is the filename portion of the mime data - payload is the content of the part - data is currently the cloud object, but this could change --- doc/examples/part-handler.txt | 12 ++++++++++++ ec2init/UserDataHandler.py | 3 ++- ec2init/__init__.py | 33 +++++++++++++++++++++++++++++---- tools/write-mime-multipart | 3 ++- 4 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 doc/examples/part-handler.txt diff --git a/doc/examples/part-handler.txt b/doc/examples/part-handler.txt new file mode 100644 index 00000000..1fe37f3a --- /dev/null +++ b/doc/examples/part-handler.txt @@ -0,0 +1,12 @@ +#part-handler +# vi: syntax=python ts=4 + +def list_types(): + return(["text/plain", "text/go-cubs-go"]) + +def handle_part(data,ctype,filename,payload): + if ctype == "__end__" or ctype == "__begin__": return + + print "==== received ctype=%s filename=%s ====" % (ctype,filename) + print payload + print "==== end ctype=%s filename=%s" % (ctype, filename) diff --git a/ec2init/UserDataHandler.py b/ec2init/UserDataHandler.py index f7c0e214..56feb0ff 100644 --- a/ec2init/UserDataHandler.py +++ b/ec2init/UserDataHandler.py @@ -8,7 +8,8 @@ starts_with_mappings={ '#include' : 'text/x-include-url', '#!' : 'text/x-shellscript', '#cloud-config' : 'text/cloud-config', - '#upstart-job' : 'text/upstart-job' + '#upstart-job' : 'text/upstart-job', + '#part-handler' : 'text/part-handler' } # if 'str' is compressed return decompressed otherwise return it diff --git a/ec2init/__init__.py b/ec2init/__init__.py index 5405b5e4..b88e3ddd 100644 --- a/ec2init/__init__.py +++ b/ec2init/__init__.py @@ -30,6 +30,7 @@ import yaml datadir = '/var/lib/cloud/data' semdir = '/var/lib/cloud/sem' +pluginsdir = datadir + '/plugins' cachedir = datadir + '/cache' userdata_raw = datadir + '/user-data.txt' userdata = datadir + '/user-data.txt.i' @@ -228,13 +229,37 @@ class EC2Init: func(data,"__end__",None,None) def handle_handler(self,data,ctype,filename,payload): - if ctype == "__begin__" or ctype == "__end__": return + if ctype == "__end__": return + if ctype == "__begin__" : + self.handlercount = 0 + return + + # add the path to the plugins dir to the top of our list for import + if self.handlercount == 0: + sys.path.insert(0,pluginsdir) + + self.handlercount=self.handlercount+1 + + # write content to pluginsdir + modname = 'part-handler-%03d' % self.handlercount + modfname = modname + ".py" + util.write_file("%s/%s" % (pluginsdir,modfname), payload, 0600) + + try: + mod = __import__(modname) + lister = getattr(mod, "list_types") + handler = getattr(mod, "handle_part") + except: + import traceback + traceback.print_exc(file=sys.stderr) + return - # - do something to include the handler, ie, eval it or something # - call it with '__begin__' + handler(data, "__begin__", None, None) + # - add it self.part_handlers - # self.part_handlers['new_type']=handler - print "Do not know what to do with a handler yet, sorry" + for mtype in lister(): + self.part_handlers[mtype]=handler def handle_user_script(self,data,ctype,filename,payload): if ctype == "__end__": return diff --git a/tools/write-mime-multipart b/tools/write-mime-multipart index b83073c1..d7ce0992 100755 --- a/tools/write-mime-multipart +++ b/tools/write-mime-multipart @@ -24,7 +24,8 @@ starts_with_mappings={ '#include' : 'text/x-include-url', '#!' : 'text/x-shellscript', '#cloud-config' : 'text/cloud-config', - '#upstart-job' : 'text/upstart-job' + '#upstart-job' : 'text/upstart-job', + '#part-handler' : 'text/part-handler' } def get_type(fname,deftype): -- cgit v1.2.3