2 # Thierry Parmentelat - INRIA
4 # class for issuing commands on a box, either local or remote
6 # the notion of 'buildname' is for providing each test run with a dir of its own
7 # buildname is generally the name of the build being tested, and can be considered unique
9 # thus 'run_in_buildname' mostly :
10 # (*) either runs locally in . - as on a local node we are already in a dedicated directory
11 # (*) or makes sure that there's a remote dir called 'buildname' and runs in it
13 # also, the copy operations
14 # (*) either do nothing if ran locally
15 # (*) or copy a local file into the remote 'buildname'
23 # inserts a backslash before each occurence of the following chars
24 # \ " ' < > & | ; ( ) $ * ~
26 def backslash_shell_specials (command):
29 if char in "\\\"'<>&|;()$*~":
35 # check main IP address against the provided hostname
37 def is_local_hostname (hostname):
38 if hostname == "localhost":
42 local_ip = socket.gethostbyname(socket.gethostname())
43 remote_ip = socket.gethostbyname(hostname)
44 return local_ip==remote_ip
46 utils.header("WARNING : something wrong in is_local_hostname with hostname=%s"%hostname)
49 def __init__(self,hostname,buildname=None,key=None, username=None):
50 self.hostname=hostname
51 self.buildname=buildname
53 self.username=username
56 return TestSsh.is_local_hostname(self.hostname)
58 std_options="-o StrictHostKeyChecking=no -o BatchMode=yes "
63 return "-i %s "%self.key
65 def hostname_part (self):
69 return "%s@%s"%(self.username,self.hostname)
71 # command gets run on the right box
72 def actual_command (self, command):
76 ssh_command += TestSsh.std_options
77 ssh_command += self.key_part()
78 ssh_command += "%s %s" %(self.hostname_part(),TestSsh.backslash_shell_specials(command))
81 def run(self, command,background=False):
82 local_command = self.actual_command(command)
85 return utils.system(local_command)
87 def clean_dir (self,dirname):
90 return self.run("rm -rf %s"%dirname)
92 def mkdir (self,dirname=None):
95 return os.path.mkdir(dirname)
98 dirname="%s/%s"%(self.buildname,dirname)
100 dirname=self.buildname
101 return self.run("mkdir -p %s"%dirname)
103 def create_buildname_once (self):
106 # create remote buildname on demand
108 self.buildname_created
111 self.buildname_created=True
113 def run_in_buildname (self,command, background=False):
115 return utils.system(command,background)
116 self.create_buildname_once()
117 return self.run("cd %s ; %s"%(self.buildname,command),background)
119 def copy (self,local_file,recursive=False):
122 self.create_buildname_once()
124 if recursive: scp_command += "-r "
125 scp_command += self.key_part()
126 scp_command += "%s %s:%s/%s"%(local_file,self.hostname_part(),
127 self.buildname,os.path.basename(local_file) or ".")
128 return utils.system(scp_command)
130 def fetch (self, remote_file, local_file, recursive=False):
133 if recursive: command += "-r "
134 command += "%s %s"%(remote_file,local_file)
137 if recursive: command += "-r "
138 command += self.key_part()
139 command += "%s:%s/%s %s"%(self.hostname_part(),self.buildname,remote_file,local_file)
140 utils.system(command)