|
6 | 6 | import subprocess |
7 | 7 | from stack.commands import Log |
8 | 8 | from stack.exception import ArgNotFound |
| 9 | +import logging |
9 | 10 |
|
10 | 11 | # Pallet info from Probepal and the database columns do not have the same names. |
11 | 12 | # They do have a mapping that ends up being the same values as one another. So |
@@ -138,34 +139,45 @@ def _get_pallet_hooks(self, operation, pallet_info): |
138 | 139 | except FileNotFoundError as exception: |
139 | 140 | self.notify(f"{script_file} specified in {hook_file} not found:\n\n{exception}") |
140 | 141 |
|
| 142 | + def log_routine(self, msg, log_methods): |
| 143 | + [ _logger(msg) for _logger in log_methods ] |
| 144 | + |
141 | 145 | def run_pallet_hooks(self, operation, pallet_info): |
| 146 | + # Setup the logger |
| 147 | + logging.basicConfig( |
| 148 | + filename="/var/log/run-pallet.log", |
| 149 | + format="%(asctime)s: %(message)s", |
| 150 | + datefmt="%Y-%m-%d %H:%M:%S", |
| 151 | + level=logging.DEBUG |
| 152 | + ) |
| 153 | + logger = logging.getLogger(__name__) |
| 154 | + |
142 | 155 | """Run the hooks for the pallet operation in progress.""" |
143 | 156 | pallet_info = self._normalize_pallet_info(pallet_info) |
144 | | - self.notify(f'checking for hooks in {PALLET_HOOK_ROOT} for {"-".join(pallet_info_getter(pallet_info))}') |
145 | | - |
| 157 | + self.log_routine(f'checking for hooks in {PALLET_HOOK_ROOT} for {"-".join(pallet_info_getter(pallet_info))}', [self.notify, logger.info]) |
146 | 158 | # Find all executable files within the script directory and sort them by name. |
147 | 159 | hooks = sorted( |
148 | 160 | self._get_pallet_hooks(operation=operation, pallet_info=pallet_info), |
149 | 161 | key=lambda script_path: script_path.name, |
150 | 162 | ) |
151 | 163 | # Execute the hooks in name sorted order. |
152 | 164 | for hook in hooks: |
153 | | - self.notify(f'running hook: {hook}') |
154 | | - Log(f'Running {operation} pallet hook for pallet {"-".join(pallet_info_getter(pallet_info))}: {hook} ') |
| 165 | + self.log_routine(f'running hook: {hook}', [self.notify]) |
| 166 | + self.log_routine(f'Running {operation} pallet hook for pallet {"-".join(pallet_info_getter(pallet_info))}: {hook} ', [Log, logger.info]) |
155 | 167 | try: |
156 | 168 | # subprocess's env mapping must be strings to strings! |
157 | 169 | environ = dict((str(k), str(v)) for k, v in asdict(pallet_info).items()) |
158 | 170 | result = self._exec(['/usr/bin/env', str(hook)], cwd=hook.parent, check=True, env=environ) |
159 | | - Log(f'Result of running {hook} (rc=={result.returncode}):') |
160 | | - Log(f'Env:\n{environ}') |
161 | | - Log(f'Stdout:\n{result.stdout}') |
162 | | - Log(f'Stderr:\n{result.stderr}') |
| 171 | + self.log_routine(f'Result of running {hook} (rc=={result.returncode}):', [Log, logger.info]) |
| 172 | + self.log_routine(f'Env:\n{environ}', [Log, logger.info]) |
| 173 | + self.log_routine(f'Stdout:\n{result.stdout}', [Log, logger.info]) |
| 174 | + self.log_routine(f'Stderr:\n{result.stderr}', [Log, logger.info]) |
163 | 175 | except (PermissionError, subprocess.CalledProcessError) as exception: |
164 | 176 | msg = f'Unable to run hook {hook}:\n\n{exception}\n' |
165 | 177 | # CalledProcessError has additional info... |
166 | 178 | if hasattr(exception, 'stdout'): |
167 | 179 | msg += f'\nstdout:\n{exception.stdout}\n\nstderr:\n{exception.stderr}' |
168 | | - self.notify(msg) |
| 180 | + self.log_routine(msg, [self.notify, logger.warning]) |
169 | 181 |
|
170 | 182 | def get_pallet_hook_directory(self, pallet_info): |
171 | 183 | """Calculate the hook directory for a given pallet.""" |
|
0 commit comments