1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 from diffpy.pdfgui.control.controlerrors import *
17 from diffpy.pdfgui.control.pdfcomponent import PDFComponent
18
20 """ServerHost holds the information about a remote machine where the
21 pdfserver process is running. It can host multiple remote pdfserver.
22
23 Data members:
24
25 servers: a list of local representatives of remote pdfserver instances
26 config: configuration dictionary of remote host
27 connection: a ssh2 connection to remote host
28 """
30 """Server is the local represetative of a remote pdfserver
31
32 pdfserver: a xmlrpclib.ServerProxy to pdfserver
33 address: a host:port string
34 busy: True if it is in use, otherwise False
35 running: True if it is running
36 connection: a ssh2 connection to remote host
37 port: remote port where pdfserver is servicing
38 """
40 """Initialize the remote server
41
42 connection -- a ssh2 connection to remote host
43 """
44 self.connection = connection
45 self.pdfserver = None
46 self.port = -1
47 self.address = ''
48
49
50
51 self.busy = True
52 self.running = False
53
54 self.__start()
55
57 """Start remote pdfserver. pdfserver.py must be in the user's PATH.
58 It chooses the remote port on which it is running.
59 """
60 command = "pdffit2server"
61 output = self.connection.execute(command)
62 try:
63 self.port = int(output.splitlines()[0])
64 except (IndexError,ValueError):
65 raise ControlRuntimeError, \
66 "Unrecognized output from remote host %s: "%self.connection.host + output
67 return
68
70 """Set up XMLRPC ServerProxy and test connection.
71 """
72 from xmlrpclib import ServerProxy
73 self.address = "http://%s:%i"%(self.connection.host, self.port)
74 transport = self.connection.getXMLRPCTransport()
75 self.pdfserver = ServerProxy(self.address,transport)
76
77 import time
78
79
80 counter = 5
81 while counter > 0 and not self.running:
82 if self.connection.owner.quit:
83 return
84 try:
85
86 time.sleep(3)
87 self.running = self.pdfserver.isRunning()
88 counter = -1
89 except ControlConnectError:
90 counter -= 1
91
92
93 if counter == 0:
94 raise ControlRuntimeError, \
95 "Can not connect to pdferver@'%s'"%self.connection.host
96
98 """Kill the server"""
99 if self.running:
100 self.pdfserver.kill_server()
101 return
102
103
125
127 """Get a pdfserver proxy
128
129 bWait -- wait for server or not (default False)
130 return: a pdfserver proxy
131 """
132 try:
133 self.lock.acquire()
134 for server in self.servers:
135 if not server.busy and server.running:
136 server.busy = True
137 return server.pdfserver
138 else:
139
140 if bWait and self.servers:
141
142 pass
143 else:
144
145 server = ServerHost.Server(self.getConnection())
146 server.connect()
147 self.servers.append(server)
148 return server.pdfserver
149 finally:
150 self.lock.release()
151
152 return None
153
155 """Release a pdfserver proxy
156
157 pdfserver -- a pdfserver proxy
158 """
159 try:
160 self.lock.acquire()
161 for server in self.servers:
162 if server.pdfserver is pdfserver:
163 server.busy = False
164 break
165 finally:
166 self.lock.release()
167 return
168
169 - def close(self, force = False):
170 """shut down connection to remote host
171
172 force -- if shut down forcefully
173 """
174 self.quit = True
175 try:
176 self.lock.acquire()
177
178 for server in self.servers[:]:
179 if server.busy and not force:
180
181 raise ControlStatusError, "ServerHost: %s is busy"%self.name
182 else:
183 server.close()
184 self.servers.remove(server)
185 finally:
186 self.lock.release()
187
188 self.connection.close()
189 return
190
192 """handle the error from connection
193
194 address -- remote pdfserver address
195 """
196 try:
197 self.lock.acquire()
198 for server in self.servers:
199 if server.address == address:
200 server.running = False
201 finally:
202 self.lock.release()
203
205 """Get a verified and connected ssh transport.
206
207 This tries to establish an ssh connection using the ssh2 protocol with a
208 preconfigured host. This uses paramiko's Agent class, which may work
209 differently on Windows.
210
211 return value: connection
212 """
213 if self.connection.isConnected():
214 return self.connection
215
216
217 import os
218 from diffpy.pdfgui.control.connection import Connection
219 try:
220
221 host = self.config['host']
222 user = self.config['username']
223 auth = self.config['authentication']
224 if self.config['use_default_port']:
225 port = Connection.DefaultPort
226 else:
227 port = int(self.config['port'])
228
229 if auth == Connection.PSWDAUTH:
230 passwd = self.config['password']
231 self.connection.connect(host,user,port,auth,passwd=passwd)
232 else:
233 if self.config['use_default_path']:
234 keyFile = os.environ['HOME'] + '/.ssh/id_rsa'
235 else:
236 keyFile = self.config['path']
237 passphrase = self.config.get('passphrase', None)
238 self.connection.connect(host,user,port,auth,keyFile=keyFile,
239 passphrase = passphrase)
240 except KeyError, error:
241 raise ControlConfigError,\
242 "ServerHost: '%s' doesn't have key '%s'"%(self.name, str(error))
243
244 return self.connection
245
246
247 if __name__ == '__main__':
248 import sys
249 import getopt
250 import getpass
251 from diffpy.pdfgui.control.connection import Connection
253 print "Usage: %s [-u user@host] [-p(passwd)|-r(rsa)|-d(dsa)]"%sys.argv[0]
254
255
256 try:
257 optlist, args = getopt.getopt(sys.argv[1:], "u:prd" )
258 except getopt.GetOptError:
259 usage()
260 sys.exit(1)
261
262 user = getpass.getuser()
263 host = 'localhost'
264 auth = Connection.RSAAUTH
265 for o,a in optlist:
266 if o == '-u':
267 user,host = a.split('@')
268 elif o == '-p':
269 auth = Connection.PSWDAUTH
270 elif o == '-r':
271 auth = Connection.RSAAUTH
272 elif o == '-d':
273 auth = Connection.DSAAUTH
274
275 config = {
276 'use_default_port' : True,
277 'use_default_path' : True,
278 'host' : host,
279 'authentication' : auth,
280 'username' : user,
281 }
282 if auth == Connection.PSWDAUTH:
283 config ['password'] = getpass.getpass("Password: ")
284
285 proxy = ServerHost(host,config)
286 pdfserver = proxy.getServer()
287
288 print "pdfserver.reset():", pdfserver.reset()
289 proxy.close(True)
290 print 'Session closed.'
291
292
293 __id__ = "$Id: serverhost.py 2980 2009-04-02 00:14:33Z juhas $"
294
295
296