Parent Directory
|
Revision Log
Revision 1.10 - (view) (download) (as text)
1 : | olson | 1.1 | import urlparse |
2 : | import socket | ||
3 : | import os | ||
4 : | olson | 1.9 | import popen2 |
5 : | olson | 1.1 | import sys |
6 : | import re | ||
7 : | olson | 1.9 | import xmlrpclib |
8 : | |||
9 : | olson | 1.1 | import FIG_Config |
10 : | |||
11 : | olson | 1.8 | import Clearinghouse |
12 : | |||
13 : | def get_clearinghouse(url = None): | ||
14 : | return Clearinghouse.Clearinghouse(url) | ||
15 : | |||
16 : | olson | 1.1 | def get_local_hostname(): |
17 : | # | ||
18 : | olson | 1.7 | # See if there is a FIGdisk/config/hostname file. If there |
19 : | # is, force the hostname to be that. | ||
20 : | # | ||
21 : | |||
22 : | try: | ||
23 : | fh = open(os.path.join(FIG_Config.fig_disk, "config", "hostname")) | ||
24 : | host = fh.readline() | ||
25 : | return host.strip() | ||
26 : | except: | ||
27 : | pass | ||
28 : | |||
29 : | # | ||
30 : | olson | 1.1 | # First check to see if we our hostname is correct. |
31 : | # | ||
32 : | # Map it to an IP address, and try to bind to that ip. | ||
33 : | # | ||
34 : | |||
35 : | hostname = socket.getfqdn() | ||
36 : | olson | 1.3 | |
37 : | olson | 1.1 | # |
38 : | olson | 1.3 | # See if hostname is something.local., which is what |
39 : | # a Mac will return if it didn't get a name via some | ||
40 : | # other mechanism (DHCP or static config). We have to | ||
41 : | # check here because otherwise it will pass the fqdn and | ||
42 : | # local binding test. | ||
43 : | olson | 1.1 | # |
44 : | |||
45 : | olson | 1.4 | if not re.search(r"\.local\.?$", hostname): |
46 : | olson | 1.3 | |
47 : | # | ||
48 : | # First check that hostname is a fqdn, and that we can bind to it. | ||
49 : | # | ||
50 : | |||
51 : | if hostname.find('.') >= 0: | ||
52 : | if try_bind(hostname): | ||
53 : | return hostname | ||
54 : | |||
55 : | olson | 1.1 | # |
56 : | # Otherwise, do a hostname lookup and try to bind to the IP address. | ||
57 : | # | ||
58 : | |||
59 : | try: | ||
60 : | ip = socket.gethostbyname(hostname) | ||
61 : | |||
62 : | except socket.error: | ||
63 : | return get_hostname_by_adapter() | ||
64 : | |||
65 : | if not try_bind(ip): | ||
66 : | |||
67 : | return get_hostname_by_adapter() | ||
68 : | |||
69 : | # | ||
70 : | # It worked. Reverse-map back to a hopefully fqdn. | ||
71 : | # | ||
72 : | |||
73 : | try: | ||
74 : | rev = socket.gethostbyaddr(ip) | ||
75 : | |||
76 : | except socket.error: | ||
77 : | |||
78 : | # | ||
79 : | # Failed, return bare IP address. | ||
80 : | # | ||
81 : | |||
82 : | return ip | ||
83 : | |||
84 : | host = rev[0] | ||
85 : | # | ||
86 : | # Check to see if we have a FQDN. | ||
87 : | # | ||
88 : | if host.find(".") >= 0: | ||
89 : | return host | ||
90 : | else: | ||
91 : | return ip | ||
92 : | |||
93 : | def try_bind(host): | ||
94 : | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | ||
95 : | try: | ||
96 : | sock.bind((host, 0)) | ||
97 : | return 1 | ||
98 : | except socket.error: | ||
99 : | return 0 | ||
100 : | |||
101 : | def get_hostname_by_adapter(): | ||
102 : | # | ||
103 : | # Attempt to determine our local hostname based on the | ||
104 : | # network environment. | ||
105 : | # | ||
106 : | # This implementation reads the routing table for the default route. | ||
107 : | # We then look at the interface config for the interface that holds the default. | ||
108 : | # | ||
109 : | # | ||
110 : | # Linux routing table: | ||
111 : | # [olson@yips 0.0.0]$ netstat -rn | ||
112 : | # Kernel IP routing table | ||
113 : | # Destination Gateway Genmask Flags MSS Window irtt Iface | ||
114 : | # 140.221.34.32 0.0.0.0 255.255.255.224 U 0 0 0 eth0 | ||
115 : | # 169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0 | ||
116 : | # 127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo | ||
117 : | # 0.0.0.0 140.221.34.61 0.0.0.0 UG 0 0 0 eth0 | ||
118 : | # | ||
119 : | # Mac routing table: | ||
120 : | # | ||
121 : | # bash-2.05a$ netstat -rn | ||
122 : | # Routing tables | ||
123 : | # | ||
124 : | # Internet: | ||
125 : | # Destination Gateway Flags Refs Use Netif Expire | ||
126 : | # default 140.221.11.253 UGSc 12 120 en0 | ||
127 : | # 127.0.0.1 127.0.0.1 UH 16 8415486 lo0 | ||
128 : | # 140.221.8/22 link#4 UCS 12 0 en0 | ||
129 : | # 140.221.8.78 0:6:5b:f:51:c4 UHLW 0 183 en0 408 | ||
130 : | # 140.221.8.191 0:3:93:84:ab:e8 UHLW 0 92 en0 622 | ||
131 : | # 140.221.8.198 0:e0:98:8e:36:e2 UHLW 0 5 en0 691 | ||
132 : | # 140.221.9.6 0:6:5b:f:51:d6 UHLW 1 63 en0 1197 | ||
133 : | # 140.221.10.135 0:d0:59:34:26:34 UHLW 2 2134 en0 1199 | ||
134 : | # 140.221.10.152 0:30:1b:b0:ec:dd UHLW 1 137 en0 1122 | ||
135 : | # 140.221.10.153 127.0.0.1 UHS 0 0 lo0 | ||
136 : | # 140.221.11.37 0:9:6b:53:4e:4b UHLW 1 624 en0 1136 | ||
137 : | # 140.221.11.103 0:30:48:22:59:e6 UHLW 3 973 en0 1016 | ||
138 : | # 140.221.11.224 0:a:95:6f:7:10 UHLW 1 1 en0 605 | ||
139 : | # 140.221.11.237 0:1:30:b8:80:c0 UHLW 0 0 en0 1158 | ||
140 : | # 140.221.11.250 0:1:30:3:1:0 UHLW 0 0 en0 1141 | ||
141 : | # 140.221.11.253 0:d0:3:e:70:a UHLW 13 0 en0 1199 | ||
142 : | # 169.254 link#4 UCS 0 0 en0 | ||
143 : | # | ||
144 : | # Internet6: | ||
145 : | # Destination Gateway Flags Netif Expire | ||
146 : | # UH lo0 | ||
147 : | # fe80::%lo0/64 Uc lo0 | ||
148 : | # link#1 UHL lo0 | ||
149 : | # fe80::%en0/64 link#4 UC en0 | ||
150 : | # 0:a:95:a8:26:68 UHL lo0 | ||
151 : | # ff01::/32 U lo0 | ||
152 : | # ff02::%lo0/32 UC lo0 | ||
153 : | # ff02::%en0/32 link#4 UC en0 | ||
154 : | |||
155 : | try: | ||
156 : | fh = os.popen("netstat -rn", "r") | ||
157 : | except: | ||
158 : | return "localhost" | ||
159 : | |||
160 : | interface_name = None | ||
161 : | for l in fh: | ||
162 : | cols = l.strip().split() | ||
163 : | |||
164 : | olson | 1.2 | if len(cols) > 0 and (cols[0] == "default" or cols[0] == "0.0.0.0"): |
165 : | olson | 1.1 | interface_name = cols[-1] |
166 : | break | ||
167 : | |||
168 : | fh.close() | ||
169 : | |||
170 : | olson | 1.2 | # print "Default route on ", interface_name |
171 : | olson | 1.1 | |
172 : | # | ||
173 : | # Find ifconfig. | ||
174 : | # | ||
175 : | |||
176 : | ifconfig = None | ||
177 : | |||
178 : | path = os.environ["PATH"].split(":") | ||
179 : | path.extend(["/sbin", "/usr/sbin"]) | ||
180 : | for p in path: | ||
181 : | i = os.path.join(p, "ifconfig") | ||
182 : | if os.access(i, os.X_OK): | ||
183 : | ifconfig = i | ||
184 : | break | ||
185 : | |||
186 : | if ifconfig is None: | ||
187 : | print >> sys.stderr, "Ifconfig not found" | ||
188 : | return "localhost" | ||
189 : | |||
190 : | olson | 1.2 | # print >> sys.stderr, "found ifconfig ", ifconfig |
191 : | olson | 1.1 | |
192 : | try: | ||
193 : | fh = os.popen(ifconfig+ " " + interface_name, "r") | ||
194 : | except: | ||
195 : | print >> sys.stderr, "Could not run ", ifconfig | ||
196 : | return "localhost" | ||
197 : | |||
198 : | ip = None | ||
199 : | |||
200 : | linux_re = re.compile("inet\s+addr:(\d+\.\d+\.\d+\.\d+)\s+") | ||
201 : | mac_re = re.compile("inet\s+(\d+\.\d+\.\d+\.\d+)\s+") | ||
202 : | |||
203 : | for l in fh: | ||
204 : | # | ||
205 : | # Mac: | ||
206 : | # inet 140.221.10.153 netmask 0xfffffc00 broadcast 140.221.11.255 | ||
207 : | # Linux: | ||
208 : | # inet addr:140.221.34.37 Bcast:140.221.34.63 Mask:255.255.255.224 | ||
209 : | # | ||
210 : | |||
211 : | l = l.strip() | ||
212 : | |||
213 : | m = linux_re.search(l) | ||
214 : | if m: | ||
215 : | # | ||
216 : | # Linux hit. | ||
217 : | # | ||
218 : | ip = m.group(1) | ||
219 : | break | ||
220 : | |||
221 : | m = mac_re.search(l) | ||
222 : | |||
223 : | if m: | ||
224 : | # | ||
225 : | # Mac hit. | ||
226 : | # | ||
227 : | ip = m.group(1) | ||
228 : | break | ||
229 : | fh.close() | ||
230 : | |||
231 : | if ip is None: | ||
232 : | print >> sys.stderr, "Didn't find an IP" | ||
233 : | return "localhost" | ||
234 : | |||
235 : | return ip | ||
236 : | |||
237 : | def cgi_url(): | ||
238 : | return plug_url(FIG_Config.cgi_url) | ||
239 : | |||
240 : | def temp_url(): | ||
241 : | return plug_url(FIG_Config.temp_url) | ||
242 : | |||
243 : | def plug_url(url): | ||
244 : | |||
245 : | name = get_local_hostname() | ||
246 : | |||
247 : | if not name: | ||
248 : | return url | ||
249 : | |||
250 : | p = urlparse.urlparse(url) | ||
251 : | |||
252 : | p = list(p) | ||
253 : | |||
254 : | p[1] = name | ||
255 : | |||
256 : | new_url = urlparse.urlunparse(p) | ||
257 : | return new_url | ||
258 : | |||
259 : | olson | 1.5 | def get_seed_id(): |
260 : | # | ||
261 : | # Retrieve the seed identifer from FIGdisk/config/seed_id. | ||
262 : | # | ||
263 : | # If it's not there, create one, and make it readonly. | ||
264 : | # | ||
265 : | |||
266 : | id_file = os.path.join(FIG_Config.fig_disk, "config", "seed_id") | ||
267 : | if not os.path.isfile(id_file): | ||
268 : | |||
269 : | fh = os.popen("uuidgen", "r") | ||
270 : | |||
271 : | newid = fh.readline() | ||
272 : | olson | 1.6 | newid = newid.strip() |
273 : | olson | 1.5 | |
274 : | fh.close() | ||
275 : | |||
276 : | fh = open(id_file, "w") | ||
277 : | print >>fh, newid | ||
278 : | fh.close() | ||
279 : | |||
280 : | os.chmod(id_file, 0444) | ||
281 : | |||
282 : | fh = open(id_file) | ||
283 : | id = fh.readline() | ||
284 : | fh.close() | ||
285 : | id = id.strip() | ||
286 : | return id | ||
287 : | |||
288 : | olson | 1.9 | # |
289 : | # Define a FIG class; this is analagous to the FIG class used in FIG.pm | ||
290 : | # | ||
291 : | # It also lets us cache stuff, and use __call__ to map calls to | ||
292 : | # an XMLRPC server for the perl stuff we don't implement locally. | ||
293 : | # | ||
294 : | |||
295 : | class FIG: | ||
296 : | |||
297 : | def __init__(self): | ||
298 : | self.xmlrpc_proxy = None | ||
299 : | self.xmlrpc_proc = None | ||
300 : | |||
301 : | def __repr__(self): | ||
302 : | return "FIG instance %s" % ( self) | ||
303 : | |||
304 : | def __str__(self): | ||
305 : | return "FIG instance %s" % (id(self)) | ||
306 : | |||
307 : | def __getattr__(self, name): | ||
308 : | g = globals() | ||
309 : | if g.has_key(name) and callable(g[name]): | ||
310 : | return g[name] | ||
311 : | |||
312 : | if name.startswith("_"): | ||
313 : | return None | ||
314 : | |||
315 : | # | ||
316 : | # Not accessible in globals. Return an XMLRPC calling proxy. | ||
317 : | # | ||
318 : | |||
319 : | return XMLRPCCaller(self, name) | ||
320 : | |||
321 : | def foo(self): | ||
322 : | print "FOO" | ||
323 : | |||
324 : | |||
325 : | def call_xmlrpc(self, name, args): | ||
326 : | |||
327 : | try: | ||
328 : | if self.xmlrpc_proxy is None: | ||
329 : | self.start_xmlrpc_server() | ||
330 : | |||
331 : | except Exception, e: | ||
332 : | print "Got exception ... ", e | ||
333 : | return | ||
334 : | |||
335 : | proc = getattr(self.xmlrpc_proxy, name) | ||
336 : | retval = apply(proc, args) | ||
337 : | return retval | ||
338 : | |||
339 : | def start_xmlrpc_server(self): | ||
340 : | olson | 1.10 | server_path = os.path.join(FIG_Config.bin, "fig_xmlrpc_server") |
341 : | olson | 1.9 | |
342 : | if not os.access(server_path, os.X_OK): | ||
343 : | raise Exception, "XMLRPC server path %s not found" % (server_path) | ||
344 : | |||
345 : | |||
346 : | proc = self.xmlrpc_proc = popen2.Popen3(server_path, 0) | ||
347 : | |||
348 : | print "Server started ", proc.pid | ||
349 : | |||
350 : | url = proc.fromchild.readline() | ||
351 : | url = url.strip() | ||
352 : | print "Read url ", url | ||
353 : | |||
354 : | proc.fromchild.close() | ||
355 : | |||
356 : | self.xmlrpc_proxy = xmlrpclib.ServerProxy(url) | ||
357 : | |||
358 : | class XMLRPCCaller: | ||
359 : | def __init__(self, fig, name): | ||
360 : | self.fig = fig | ||
361 : | self.name = name | ||
362 : | |||
363 : | def __call__(self, *args): | ||
364 : | return self.fig.call_xmlrpc(self.name, args) | ||
365 : | |||
366 : | olson | 1.1 | if __name__ == "__main__": |
367 : | |||
368 : | print get_local_hostname() | ||
369 : | print cgi_url() | ||
370 : | print temp_url() | ||
371 : | olson | 1.5 | |
372 : | print get_seed_id() |
MCS Webmaster | ViewVC Help |
Powered by ViewVC 1.0.3 |