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 |
29 def list_remote_pythons(host): | 38 def list_remote_pythons(host): |
30 """List out installed pythons on host.""" | 39 """List out installed pythons on host.""" |
31 result = host.run('ls /usr/bin/python[0-9]*') | 40 result = host.run('ls /usr/bin/python[0-9]*') |
32 return result.stdout.splitlines() | 41 return result.stdout.splitlines() |
33 | 42 |
34 | 43 |
35 def select_supported_python(installed_pythons): | 44 def select_supported_python(installed_pythons): |
36 """Select a supported python from a list""" | 45 """Select a supported python from a list""" |
37 for python in installed_pythons: | 46 for python in installed_pythons: |
38 if python[-3:] in SUPPORTED_PYTHON_VERS: | 47 if python[-3:] in SUPPORTED_PYTHON_VERS: |
(...skipping 17 matching lines...) Expand all Loading... |
56 supported_python = select_supported_python(installed_pythons) | 65 supported_python = select_supported_python(installed_pythons) |
57 if not supported_python: | 66 if not supported_python: |
58 if DEFAULT_PYTHON in installed_pythons: | 67 if DEFAULT_PYTHON in installed_pythons: |
59 logging.info('No versioned Python binary found, ' | 68 logging.info('No versioned Python binary found, ' |
60 'defaulting to: %s', DEFAULT_PYTHON) | 69 'defaulting to: %s', DEFAULT_PYTHON) |
61 supported_python = DEFAULT_PYTHON | 70 supported_python = DEFAULT_PYTHON |
62 else: | 71 else: |
63 raise FollowFilesLaunchError('No supported Python on host.') | 72 raise FollowFilesLaunchError('No supported Python on host.') |
64 | 73 |
65 remote_monitordir = copy_monitordir(host) | 74 remote_monitordir = copy_monitordir(host) |
66 remote_script_path = os.path.join(remote_monitordir, 'followfiles.py') | 75 remote_script_path = os.path.join( |
| 76 remote_monitordir, 'followfiles.py') |
67 | 77 |
68 followfiles_cmd = '%s %s --lastlines_dirpath=%s %s' % ( | 78 followfiles_cmd = '%s %s --lastlines_dirpath=%s %s' % ( |
69 supported_python, remote_script_path, | 79 supported_python, remote_script_path, |
70 lastlines_dirpath, ' '.join(follow_paths)) | 80 lastlines_dirpath, ' '.join(follow_paths)) |
71 | 81 |
72 remote_ff_proc = subprocess.Popen(host._make_ssh_cmd(followfiles_cmd), | 82 devnull_r = open(os.devnull, 'r') |
73 stdin=open(os.devnull, 'r'), | 83 devnull_w = open(os.devnull, 'w') |
74 stdout=subprocess.PIPE, shell=True) | 84 remote_followfiles_proc = run_cmd_on_host( |
75 | 85 host.hostname, followfiles_cmd, stdout=subprocess.PIPE, |
76 | 86 stdin=devnull_r, stderr=devnull_w) |
77 # Give it enough time to crash if it's going to (it shouldn't). | 87 # Give it enough time to crash if it's going to (it shouldn't). |
78 time.sleep(5) | 88 time.sleep(5) |
79 doa = remote_ff_proc.poll() | 89 doa = remote_followfiles_proc.poll() |
80 if doa: | 90 if doa: |
81 raise FollowFilesLaunchError('ssh command crashed.') | 91 raise FollowFilesLaunchError('ssh command crashed.') |
82 | 92 |
83 return remote_ff_proc | 93 return remote_followfiles_proc |
84 | 94 |
85 | 95 |
86 def resolve_patterns_path(patterns_path): | 96 def resolve_patterns_path(patterns_path): |
87 """Resolve patterns_path to existing absolute local path or raise. | 97 """Resolve patterns_path to existing absolute local path or raise. |
88 | 98 |
89 As a convenience we allow users to specify a non-absolute patterns_path. | 99 As a convenience we allow users to specify a non-absolute patterns_path. |
90 However these need to be resolved before allowing them to be passed down | 100 However these need to be resolved before allowing them to be passed down |
91 to console.py. | 101 to console.py. |
92 | 102 |
93 For now we expect non-absolute ones to be in self.monitordir. | 103 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... |
282 pattern_paths: list; Local alert pattern definition files. | 292 pattern_paths: list; Local alert pattern definition files. |
283 """ | 293 """ |
284 if not follow_paths or (pattern_paths and not follow_paths): | 294 if not follow_paths or (pattern_paths and not follow_paths): |
285 raise InvalidConfigurationError | 295 raise InvalidConfigurationError |
286 | 296 |
287 return type( | 297 return type( |
288 'LogfileMonitorMixin%d' % id(follow_paths), | 298 'LogfileMonitorMixin%d' % id(follow_paths), |
289 (LogfileMonitorMixin,), | 299 (LogfileMonitorMixin,), |
290 {'follow_paths': follow_paths, | 300 {'follow_paths': follow_paths, |
291 'pattern_paths': pattern_paths or ()}) | 301 'pattern_paths': pattern_paths or ()}) |
OLD | NEW |