#!/usr/bin/python ## ## func yaml wrapper tool. ## allows usage of func over stdin/stdin using yaml as a marshalling format ## for access to the Overlord() API from non-Python code. ## this should typically be accessed via a pipe, though also works as ## func-transmit < yamlfile ## ## Copyright 2008, Various ## Marco Mornati ## Michael DeHaan ## Adrian Likins ## ## This software may be freely redistributed under the terms of the GNU ## general public license. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ## ## Example yaml input file format: """ clients: "*" aysnc: False nforks: 1 module: command method: run parameters: "/bin/echo Hello World" """ import exceptions import string import sys import distutils.sysconfig import optparse import simplejson import func.overlord.func_command as func_command import func.overlord.client as fc import func.yaml as yaml import func.CommonErrors class NoAsyncForListMinionException(exceptions.Exception): def __init__(self, msg): self.msg = msg # scan arguments class FuncTransmitError(object): def __init__(self, name="", message="", info={}): self.data = {'error':1, # not all of the marshall types support bools, so 1 will have to do 'name':name, 'message':message, 'info':info} def is_a_list(item): if type(item) in [type([]), type(())]: return True return False def read_data(format, data): if format == "yaml": params = yaml.load(data).next() elif format == "json": params = simplejson.loads(data) return params def write_data(format, data): # convert to selected language (default is JSON) if format == "json": output = simplejson.dumps(data) elif format == "yaml": output = yaml.dump(data) print output def main(argv): # load input parameters parser = optparse.OptionParser() parser.add_option("-j","--json", help="Json Parser", action="store_true", dest="json", default=False) parser.add_option("-y","--yaml", help="Yaml Parser", action="store_true", dest="yaml", default=False) (options,args) = parser.parse_args() # load input from stdin input = sys.stdin.read() # Setting default language if no one is selected by user if (options.json==False and options.yaml==False): options.json = True format = "json" if (options.yaml): format = "yaml" params = read_data(format, input) # slightly odd, but we expect clients to be a string we parse # out later (glob and group expansion, etc). So if it is a list, # flatten it into a string. clients = params.get('clients', "*") if is_a_list(clients): clients = string.join(clients,';') method = params.get('method','unknown') async = params.get('async', False) # scan more arguments nforks = params.get('nforks', 1) module = params.get('module', None) parameters = params.get('parameters', None) # make the call try: client = fc.Overlord(clients, async=async, nforks=nforks) except func.CommonErrors.Func_Client_Exception, e: error = FuncTransmitError("Func Client Exception", str(e)) write_data(format, error.data) return 1 if module is None: method_handle = getattr(client, method) else: module_handle = getattr(client, module) method_handle = getattr(module_handle, method) if parameters is not None: # listify if we get something thats not a list if not is_a_list(parameters): parameters = [parameters] results = method_handle(*parameters) else: results = method_handle() # convert to selected language (default is JSON) and output write_data(format, results) return 0 if __name__ == "__main__": sys.exit(main(sys.argv))