attempt to avoid remote qemus from hanging
[tests.git] / system / TestSsh.py
1 #this class is  used for any ssh command and
2 #also for any remote or a local command independently
3 #on which box this must be done.
4
5 import os.path
6 import utils
7
8 class TestSsh:
9     
10     # inserts a backslash before each occurence of the following chars
11     # \ " ' < > & | ; ( ) $ * ~ 
12     @staticmethod
13     def backslash_shell_specials (command):
14         result=''
15         for char in command:
16             if char in "\\\"'<>&|;()$*~":
17                 result +='\\'+char
18             else:
19                 result +=char
20         return result
21
22     # check main IP address against the provided hostname
23     @staticmethod
24     def is_local_hostname (hostname):
25         if hostname == "localhost":
26             return True
27         import socket
28         try:
29             local_ip = socket.gethostbyname(socket.gethostname())
30             remote_ip = socket.gethostbyname(hostname)
31             return local_ip==remote_ip
32         except:
33             utils.header("WARNING : something wrong in is_local_hostname with hostname=%s"%hostname)
34             return False
35
36     def __init__(self,hostname,buildname=None,key=None):
37         self.hostname=hostname
38         self.buildname=buildname
39         self.key=key
40
41     def is_local(self):
42         return TestSsh.is_local_hostname(self.hostname)
43      
44     std_options="-o StrictHostKeyChecking=no -o BatchMode=yes "
45     
46     def key_part (self):
47         if not self.key:
48             return ""
49         return "-i %s.rsa "%self.key
50     
51     # command gets run on the right box
52     def actual_command (self, command):
53         if self.is_local():
54             return command
55         ssh_command = "ssh "
56         ssh_command += TestSsh.std_options
57         ssh_command += self.key_part()
58         ssh_command += "%s %s" %(self.hostname,TestSsh.backslash_shell_specials(command))
59         return ssh_command
60
61     def run(self, command,background=False):
62         local_command = self.actual_command(command)
63         if background:
64             local_command += " &"
65         return utils.system(local_command)
66
67     def clean_dir (self,dirname):
68         if self.is_local():
69             return 0
70         return self.run("rm -rf %s"%dirname)
71
72     def mkdir (self,dirname=None):
73         if self.is_local():
74             if dirname:
75                 return os.path.mkdir(dirname)
76             return 0
77         if dirname:
78             dirname="%s/%s"%(self.buildname,dirname)
79         else:
80             dirname=self.buildname
81         return self.run("mkdir %s"%dirname)
82
83     def create_buildname_once (self):
84         if self.is_local():
85             return
86         # create remote buildname on demand
87         try:
88             self.buildname_created
89         except:
90             self.mkdir()
91             self.buildname_created=True
92
93     def run_in_buildname (self,command, background=False):
94         if self.is_local():
95             return utils.system(command)
96         self.create_buildname_once()
97         return self.run("cd %s ; %s"%(self.buildname,command),background)
98
99     def copy (self,local_file,recursive=False):
100         if self.is_local():
101             return 0
102         self.create_buildname_once()
103         scp_command="scp "
104         if recursive: scp_command += "-r "
105         scp_command += self.key_part()
106         scp_command += "%s %s:%s/%s"%(local_file,self.hostname,self.buildname,
107                                       os.path.basename(local_file) or ".")
108         return utils.system(scp_command)
109