00001 __copyright__ = """
00002 Copyright 2008 Sean Ross-Ross
00003 """
00004 __license__ = """
00005 This file is part of SLIMpy .
00006
00007 SLIMpy is free software: you can redistribute it and/or modify
00008 it under the terms of the GNU Lesser General Public License as published by
00009 the Free Software Foundation, either version 3 of the License, or
00010 (at your option) any later version.
00011
00012 SLIMpy is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00015 GNU Lesser General Public License for more details.
00016
00017 You should have received a copy of the GNU Lesser General Public License
00018 along with SLIMpy . If not, see <http://www.gnu.org/licenses/>.
00019 """
00020
00021 from string import Template
00022
00023
00024 from slimpy_base.Environment.InstanceManager import InstanceManager
00025 from itertools import starmap
00026 from os import sep
00027
00028 def gethostname():
00029 import os
00030 return os.uname()[1]
00031
00032 def is_localhost( nodename ):
00033 if nodename is None:
00034 return True
00035 if isinstance(nodename, str):
00036 if nodename == 'localhost':
00037 return True
00038 if nodename == gethostname():
00039 return True
00040 else:
00041 return False
00042
00043 class Unix_Pipes( object ):
00044
00045 env = InstanceManager()
00046 JOIN_PIPE = " | ".join
00047
00048
00049 @classmethod
00050 def prepend_datapath(cls, is_loc, is_tmp , com):
00051 '''
00052 choose a datapath from one of the global variables localtmpdir,
00053 globaltmpdir or datapath.
00054 return com augmented by "DATAPATH=%(dp)s %(com)s"
00055 '''
00056 local_dp = "DATAPATH=%s" % cls.env['slimvars']['localtmpdir'] + sep
00057 tmp_global_dp = "DATAPATH=%s" % cls.env['slimvars']['globaltmpdir'] + sep
00058 global_dp = "DATAPATH=%s" % cls.env['slimvars']['datapath'] + sep
00059
00060 if is_tmp:
00061 if is_loc:
00062 dp = local_dp
00063 elif is_loc is False:
00064 dp = tmp_global_dp
00065 else:
00066 dp = False
00067 elif is_tmp is False:
00068 dp = global_dp
00069 else:
00070 dp = None
00071
00072 if dp:
00073 return "%s %s" %( dp, com )
00074 else:
00075 return com
00076
00077 @classmethod
00078 def pipe_join( cls, cmd_list, is_local=None,is_tmp=None ):
00079 """
00080 join cmand
00081 """
00082
00083 if is_tmp is None: is_tmp = [None] * len(cmd_list)
00084 if is_local is None: is_local = [None] * len(cmd_list)
00085 assert len(is_tmp) == len(is_local) == len(cmd_list), "not a user error. should not get here"
00086
00087 loc_tmp_cmd = zip(is_local,is_tmp, cmd_list)
00088
00089 star = starmap( cls.prepend_datapath, loc_tmp_cmd )
00090
00091 ret = cls.JOIN_PIPE( star )
00092 return ret
00093
00094 @classmethod
00095 def stdout_join(cls, cmd, outfile):
00096 return " 1> ".join([cmd,outfile])
00097
00098 @classmethod
00099 def stderr_join( cls, cmd, outfile):
00100 return " 2> ".join([cmd,outfile])
00101
00102 @classmethod
00103 def sub( cls, targ, **kargs):
00104 '''
00105 Unix_Pipes.sub( targ, **kargs )
00106 creates a string.Template from targ and sub in kargs
00107 '''
00108 return Template( targ ).substitute( **kargs )
00109
00110
00111 @classmethod
00112 def stdin_join( cls, infile, cmd):
00113 return "< %s %s" %(infile,cmd)
00114
00115 file_in_out = "< ${STD_IN} ${COMMAND} > ${STD_OUT}"
00116 file_out = "${COMMAND} > ${STD_OUT}"
00117 file_in = "< ${STD_IN} ${COMMAND}"
00118 file_ = "${COMMAND}"
00119 rsh = '${RSH} ${NODE} "${COMMAND}"'
00120
00121
00122
00123
00124
00125 @classmethod
00126 def replace_quotes(cls,cmd):
00127 cmd = cmd.replace('\\"','\\\\"')
00128 return cmd.replace('"','\\"')
00129
00130 @classmethod
00131 def CreateComand( cls, cmdlist, node_name=None ,
00132 source=None, target=None,
00133 is_local=None,is_tmp=None, err=None, ssh_localhost=False):
00134
00135 cmd = cls.pipe_join( cmdlist, is_local, is_tmp)
00136
00137
00138
00139 if source:
00140 if target:
00141
00142 cmd = cls.sub( cls.file_in_out, STD_IN=source, COMMAND=cmd, STD_OUT=target )
00143 else:
00144 cmd = cls.sub( cls.file_in, STD_IN=source, COMMAND=cmd )
00145 elif target:
00146 cmd = cls.sub( cls.file_out, COMMAND=cmd, STD_OUT=target )
00147 else:
00148 cmd = cls.sub( cls.file_, COMMAND=cmd )
00149
00150 if err:
00151 cmd = cls.stderr_join( cmd, err )
00152
00153 if ssh_localhost or not is_localhost(node_name) :
00154
00155 if is_localhost(node_name):
00156 node_name = gethostname()
00157
00158 cmd = cls.replace_quotes(cmd)
00159 cmd = cls.sub( cls.rsh,
00160 RSH=cls.env['slimvars']['rsh'],
00161 NODE=node_name,
00162 COMMAND=cmd )
00163 return cmd
00164