OLD | NEW |
1 import logging, os, sys, subprocess, tempfile, traceback | 1 import logging, os, sys, subprocess, tempfile, traceback |
2 import time | 2 import time |
3 | 3 |
4 from autotest_lib.client.common_lib import utils | 4 from autotest_lib.client.common_lib import utils |
5 from autotest_lib.server import utils as server_utils | 5 from autotest_lib.server import utils as server_utils |
6 from autotest_lib.server.hosts import abstract_ssh, monitors | 6 from autotest_lib.server.hosts import abstract_ssh, monitors |
7 | 7 |
8 MONITORDIR = monitors.__path__[0] | 8 MONITORDIR = monitors.__path__[0] |
9 SUPPORTED_PYTHON_VERS = ('2.4', '2.5', '2.6') | 9 SUPPORTED_PYTHON_VERS = ('2.4', '2.5', '2.6') |
10 DEFAULT_PYTHON = '/usr/bin/python' | 10 DEFAULT_PYTHON = '/usr/bin/python' |
11 | 11 |
12 | 12 |
13 class Error(Exception): | 13 class Error(Exception): |
14 pass | 14 pass |
15 | 15 |
16 | 16 |
17 class InvalidPatternsPathError(Error): | 17 class InvalidPatternsPathError(Error): |
18 """An invalid patterns_path was specified.""" | 18 """An invalid patterns_path was specified.""" |
19 | 19 |
20 | 20 |
21 class InvalidConfigurationError(Error): | 21 class InvalidConfigurationError(Error): |
22 """An invalid configuration was specified.""" | 22 """An invalid configuration was specified.""" |
23 | 23 |
24 | 24 |
25 class FollowFilesLaunchError(Error): | 25 class FollowFilesLaunchError(Error): |
26 """Error occurred launching followfiles remotely.""" | 26 """Error occurred launching followfiles remotely.""" |
27 | 27 |
28 | 28 |
29 def run_cmd_on_host(hostname, cmd, stdin, stdout, stderr): | |
30 base_cmd = abstract_ssh.make_ssh_command() | |
31 full_cmd = "%s %s \"%s\"" % (base_cmd, hostname, | |
32 server_utils.sh_escape(cmd)) | |
33 | |
34 return subprocess.Popen(full_cmd, stdin=stdin, stdout=stdout, | |
35 stderr=stderr, shell=True) | |
36 | |
37 | |
38 def list_remote_pythons(host): | 29 def list_remote_pythons(host): |
39 """List out installed pythons on host.""" | 30 """List out installed pythons on host.""" |
40 result = host.run('ls /usr/bin/python[0-9]*') | 31 result = host.run('ls /usr/bin/python[0-9]*') |
41 return result.stdout.splitlines() | 32 return result.stdout.splitlines() |
42 | 33 |
43 | 34 |
44 def select_supported_python(installed_pythons): | 35 def select_supported_python(installed_pythons): |
45 """Select a supported python from a list""" | 36 """Select a supported python from a list""" |
46 for python in installed_pythons: | 37 for python in installed_pythons: |
47 if python[-3:] in SUPPORTED_PYTHON_VERS: | 38 if python[-3:] in SUPPORTED_PYTHON_VERS: |
(...skipping 17 matching lines...) Expand all Loading... |
65 supported_python = select_supported_python(installed_pythons) | 56 supported_python = select_supported_python(installed_pythons) |
66 if not supported_python: | 57 if not supported_python: |
67 if DEFAULT_PYTHON in installed_pythons: | 58 if DEFAULT_PYTHON in installed_pythons: |
68 logging.info('No versioned Python binary found, ' | 59 logging.info('No versioned Python binary found, ' |
69 'defaulting to: %s', DEFAULT_PYTHON) | 60 'defaulting to: %s', DEFAULT_PYTHON) |
70 supported_python = DEFAULT_PYTHON | 61 supported_python = DEFAULT_PYTHON |
71 else: | 62 else: |
72 raise FollowFilesLaunchError('No supported Python on host.') | 63 raise FollowFilesLaunchError('No supported Python on host.') |
73 | 64 |
74 remote_monitordir = copy_monitordir(host) | 65 remote_monitordir = copy_monitordir(host) |
75 remote_script_path = os.path.join( | 66 remote_script_path = os.path.join(remote_monitordir, 'followfiles.py') |
76 remote_monitordir, 'followfiles.py') | |
77 | 67 |
78 followfiles_cmd = '%s %s --lastlines_dirpath=%s %s' % ( | 68 followfiles_cmd = '%s %s --lastlines_dirpath=%s %s' % ( |
79 supported_python, remote_script_path, | 69 supported_python, remote_script_path, |
80 lastlines_dirpath, ' '.join(follow_paths)) | 70 lastlines_dirpath, ' '.join(follow_paths)) |
81 | 71 |
82 devnull_r = open(os.devnull, 'r') | 72 remote_ff_proc = subprocess.Popen(host._make_ssh_cmd(followfiles_cmd), |
83 devnull_w = open(os.devnull, 'w') | 73 stdin=open(os.devnull, 'r'), |
84 remote_followfiles_proc = run_cmd_on_host( | 74 stdout=subprocess.PIPE, shell=True) |
85 host.hostname, followfiles_cmd, stdout=subprocess.PIPE, | 75 |
86 stdin=devnull_r, stderr=devnull_w) | 76 |
87 # Give it enough time to crash if it's going to (it shouldn't). | 77 # Give it enough time to crash if it's going to (it shouldn't). |
88 time.sleep(5) | 78 time.sleep(5) |
89 doa = remote_followfiles_proc.poll() | 79 doa = remote_ff_proc.poll() |
90 if doa: | 80 if doa: |
91 raise FollowFilesLaunchError('ssh command crashed.') | 81 raise FollowFilesLaunchError('ssh command crashed.') |
92 | 82 |
93 return remote_followfiles_proc | 83 return remote_ff_proc |
94 | 84 |
95 | 85 |
96 def resolve_patterns_path(patterns_path): | 86 def resolve_patterns_path(patterns_path): |
97 """Resolve patterns_path to existing absolute local path or raise. | 87 """Resolve patterns_path to existing absolute local path or raise. |
98 | 88 |
99 As a convenience we allow users to specify a non-absolute patterns_path. | 89 As a convenience we allow users to specify a non-absolute patterns_path. |
100 However these need to be resolved before allowing them to be passed down | 90 However these need to be resolved before allowing them to be passed down |
101 to console.py. | 91 to console.py. |
102 | 92 |
103 For now we expect non-absolute ones to be in self.monitordir. | 93 For now we expect non-absolute ones to be in self.monitordir. |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 pattern_paths: list; Local alert pattern definition files. | 282 pattern_paths: list; Local alert pattern definition files. |
293 """ | 283 """ |
294 if not follow_paths or (pattern_paths and not follow_paths): | 284 if not follow_paths or (pattern_paths and not follow_paths): |
295 raise InvalidConfigurationError | 285 raise InvalidConfigurationError |
296 | 286 |
297 return type( | 287 return type( |
298 'LogfileMonitorMixin%d' % id(follow_paths), | 288 'LogfileMonitorMixin%d' % id(follow_paths), |
299 (LogfileMonitorMixin,), | 289 (LogfileMonitorMixin,), |
300 {'follow_paths': follow_paths, | 290 {'follow_paths': follow_paths, |
301 'pattern_paths': pattern_paths or ()}) | 291 'pattern_paths': pattern_paths or ()}) |
OLD | NEW |