Merge lp:~javier.collado/utah/retry-timeout into lp:utah

Proposed by Javier Collado
Status: Merged
Merged at revision: 833
Proposed branch: lp:~javier.collado/utah/retry-timeout
Merge into: lp:utah
Diff against target: 264 lines (+34/-55)
9 files modified
utah/client/runner.py (+0/-3)
utah/config.py (+4/-1)
utah/exceptions.py (+1/-4)
utah/provisioning/baremetal/bamboofeeder.py (+2/-1)
utah/provisioning/baremetal/cobbler.py (+2/-2)
utah/provisioning/provisioning.py (+3/-17)
utah/provisioning/ssh.py (+3/-15)
utah/retry.py (+19/-9)
utah/url.py (+0/-3)
To merge this branch: bzr merge lp:~javier.collado/utah/retry-timeout
Reviewer Review Type Date Requested Status
Max Brustkern (community) Approve
Review via email: mp+153198@code.launchpad.net

Description of the change

This branch moves the different time.sleep calls in methods like `pingcheck`
and `sshcheck` to the `retry` function that is already wrapping them.

Before this change `retry` called the callable passed as argument as soon as a
retriable exception was caught and was the responsibiliy of the callable to
call `time.sleep` if needed. With this change, the `retry` takes care of that
and uses a default value from the configuration file so that callables only
need to take care of raising an exception when they fail.

To post a comment you must log in.
Revision history for this message
Max Brustkern (nuclearbob) wrote :

I see some merge conflicts. It seems weird that this and the rsyslog branch have been getting them lately. I wonder if there's been a change in launchpad that's causing this.

Revision history for this message
Max Brustkern (nuclearbob) wrote :

The actual changes look sound. I think at some point when we overhaul config, we can address the circular import problem.

Revision history for this message
Andy Doan (doanac) wrote :

these are real merge conflicts. minus those, i like the changes.

832. By Javier Collado

Merged changes to fix battery behavior with regard to logging

Source branch: lp:~javier.collado/utah/battery-measurements-logging

Revision history for this message
Javier Collado (javier.collado) wrote :

I've rebased the changes and the merge conflicts are not fixed.

I've run a test and everything worked fine, but I believe the code wasn't
really exercised because rsyslog implementation does a good work in monitoring
the reboot after the installation so the first ping command doesn't fail in VMs
as it used to do in the past.

Anyway, since I tested already before the rebasing, I don't expect any
problem.

Revision history for this message
Max Brustkern (nuclearbob) wrote :

Looks reasonable to me, if you're already tested.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'utah/client/runner.py'
--- utah/client/runner.py 2013-03-11 09:17:54 +0000
+++ utah/client/runner.py 2013-03-14 17:40:27 +0000
@@ -31,7 +31,6 @@
31import stat31import stat
32import urllib32import urllib
33import jsonschema33import jsonschema
34import time
3534
36from utah.client.common import (35from utah.client.common import (
37 MASTER_RUNLIST,36 MASTER_RUNLIST,
@@ -472,8 +471,6 @@
472 if (isinstance(vcs_handler, BzrHandler) and471 if (isinstance(vcs_handler, BzrHandler) and
473 result['returncode'] == 3 and472 result['returncode'] == 3 and
474 'Unable to handle http code 502' in result['stderr']):473 'Unable to handle http code 502' in result['stderr']):
475 # Separate every retry attempt with a timeout of 3 seconds
476 time.sleep(3)
477 raise UTAHException('Launchpad temporary error detected',474 raise UTAHException('Launchpad temporary error detected',
478 retry=True)475 retry=True)
479 return result476 return result
480477
=== modified file 'utah/config.py'
--- utah/config.py 2013-03-12 16:10:49 +0000
+++ utah/config.py 2013-03-14 17:40:27 +0000
@@ -186,7 +186,10 @@
186 'pattern': '.*NetworkManager',186 'pattern': '.*NetworkManager',
187 'timeout': 180,187 'timeout': 180,
188 }188 }
189 ]189 ],
190
191 # default timeout between retry attempts
192 retry_timeout=3,
190)193)
191194
192# These depend on the local user/path, and need to be filtered out195# These depend on the local user/path, and need to be filtered out
193196
=== modified file 'utah/exceptions.py'
--- utah/exceptions.py 2012-12-03 14:02:18 +0000
+++ utah/exceptions.py 2013-03-14 17:40:27 +0000
@@ -24,8 +24,5 @@
24 Support retry argument, but default to False.24 Support retry argument, but default to False.
25 """25 """
26 def __init__(self, *args, **kw):26 def __init__(self, *args, **kw):
27 try:27 self.retry = kw.pop('retry', False)
28 self.retry = kw.pop('retry')
29 except KeyError:
30 self.retry = False
31 super(UTAHException, self).__init__(*args, **kw)28 super(UTAHException, self).__init__(*args, **kw)
3229
=== modified file 'utah/provisioning/baremetal/bamboofeeder.py'
--- utah/provisioning/baremetal/bamboofeeder.py 2013-03-05 21:01:23 +0000
+++ utah/provisioning/baremetal/bamboofeeder.py 2013-03-14 17:40:27 +0000
@@ -275,7 +275,8 @@
275275
276 self.rsyslog.wait_for_install(config.install_steps)276 self.rsyslog.wait_for_install(config.install_steps)
277 self.rsyslog.wait_for_booted(config.boot_steps)277 self.rsyslog.wait_for_booted(config.boot_steps)
278 retry(self.sshcheck, config.checktimeout, logmethod=self.logger.info)278 retry(self.sshcheck, logmethod=self.logger.info,
279 retry_timeout=config.checktimeout)
279280
280 self.provisioned = True281 self.provisioned = True
281 self.active = True282 self.active = True
282283
=== modified file 'utah/provisioning/baremetal/cobbler.py'
--- utah/provisioning/baremetal/cobbler.py 2013-03-05 21:01:23 +0000
+++ utah/provisioning/baremetal/cobbler.py 2013-03-14 17:40:27 +0000
@@ -21,7 +21,6 @@
21import pipes21import pipes
22import subprocess22import subprocess
23import tempfile23import tempfile
24import time
2524
26from utah import config25from utah import config
27from utah.provisioning.baremetal.exceptions import UTAHBMProvisioningException26from utah.provisioning.baremetal.exceptions import UTAHBMProvisioningException
@@ -198,7 +197,8 @@
198 if self.installtype == 'desktop':197 if self.installtype == 'desktop':
199 self._removenfs()198 self._removenfs()
200199
201 retry(self.sshcheck, config.checktimeout, logmethod=self.logger.info)200 retry(self.sshcheck, logmethod=self.logger.info,
201 retry_timeout=config.checktimeout)
202202
203 self.provisioned = True203 self.provisioned = True
204 self.active = True204 self.active = True
205205
=== modified file 'utah/provisioning/provisioning.py'
--- utah/provisioning/provisioning.py 2013-03-05 21:03:09 +0000
+++ utah/provisioning/provisioning.py 2013-03-14 17:40:27 +0000
@@ -28,7 +28,6 @@
28import shutil28import shutil
29import subprocess29import subprocess
30import sys30import sys
31import time
32import urllib31import urllib
33import uuid32import uuid
3433
@@ -310,16 +309,9 @@
310 if not self.active:309 if not self.active:
311 self._start()310 self._start()
312311
313 def pingcheck(self, timeout=config.checktimeout):312 def pingcheck(self):
314 """Check network connectivity using ping.313 """Check network connectivity using ping.
315314
316 :param timeout: Amount of time in seconds to sleep after a failure
317 :type timeout: int
318 :raises: UTAHProvisioningException
319
320 If there's a network connectivity failure, then sleep ``timeout``
321 seconds and raise a retriable exception.
322
323 .. seealso:: :func:`utah.retry.retry`, :meth:`pingpoll`315 .. seealso:: :func:`utah.retry.retry`, :meth:`pingpoll`
324316
325 """317 """
@@ -328,12 +320,6 @@
328 self._runargs(['ping', '-c1', '-w5', self.name])['returncode']320 self._runargs(['ping', '-c1', '-w5', self.name])['returncode']
329 if returncode != 0:321 if returncode != 0:
330 err = 'Ping returned {0}'.format(returncode)322 err = 'Ping returned {0}'.format(returncode)
331
332 if timeout > 0:
333 self.logger.info('Sleeping {timeout} seconds'
334 .format(timeout=timeout))
335 time.sleep(timeout)
336
337 raise UTAHProvisioningException(err, retry=True)323 raise UTAHProvisioningException(err, retry=True)
338324
339 def pingpoll(self,325 def pingpoll(self,
@@ -345,8 +331,8 @@
345 timeout = self.boottimeout331 timeout = self.boottimeout
346 if logmethod is None:332 if logmethod is None:
347 logmethod = self.logger.debug333 logmethod = self.logger.debug
348 utah.timeout.timeout(timeout, retry, self.pingcheck, checktimeout,334 utah.timeout.timeout(timeout, retry, self.pingcheck,
349 logmethod=logmethod)335 logmethod=logmethod, retry_timeout=checktimeout)
350336
351 def getutahdeb(self, deb):337 def getutahdeb(self, deb):
352 """338 """
353339
=== modified file 'utah/provisioning/ssh.py'
--- utah/provisioning/ssh.py 2013-03-07 21:55:56 +0000
+++ utah/provisioning/ssh.py 2013-03-14 17:40:27 +0000
@@ -238,16 +238,9 @@
238238
239 super(SSHMixin, self).destroy(*args, **kw)239 super(SSHMixin, self).destroy(*args, **kw)
240240
241 def sshcheck(self, timeout=config.checktimeout):241 def sshcheck(self):
242 """Check if the machine is available via ssh.242 """Check if the machine is available via ssh.
243243
244 :param timeout: Amount of time in seconds to sleep after a failure
245 :type timeout: int
246 :raises: UTAHProvisioningException
247
248 If there's a network connectivity failure, then sleep ``timeout``
249 seconds and raise a retriable exception.
250
251 .. seealso:: :func:`utah.retry.retry`, :meth:`sshpoll`244 .. seealso:: :func:`utah.retry.retry`, :meth:`sshpoll`
252245
253 """246 """
@@ -257,11 +250,6 @@
257 username=config.user,250 username=config.user,
258 key_filename=config.sshprivatekey)251 key_filename=config.sshprivatekey)
259 except socket.error as err:252 except socket.error as err:
260 if timeout > 0:
261 self.ssh_logger.info('Sleeping {timeout} seconds'
262 .format(timeout=timeout))
263 time.sleep(timeout)
264
265 raise UTAHProvisioningException(str(err), retry=True)253 raise UTAHProvisioningException(str(err), retry=True)
266254
267 def sshpoll(self, timeout=None,255 def sshpoll(self, timeout=None,
@@ -273,8 +261,8 @@
273 timeout = self.boottimeout261 timeout = self.boottimeout
274 if logmethod is None:262 if logmethod is None:
275 logmethod = self.ssh_logger.debug263 logmethod = self.ssh_logger.debug
276 utah.timeout.timeout(timeout, retry, self.sshcheck, checktimeout,264 utah.timeout.timeout(timeout, retry, self.sshcheck,
277 logmethod=logmethod)265 logmethod=logmethod, retry_timeout=checktimeout)
278266
279 def activecheck(self):267 def activecheck(self):
280 """268 """
281269
=== modified file 'utah/retry.py'
--- utah/retry.py 2013-02-06 10:53:54 +0000
+++ utah/retry.py 2013-03-14 17:40:27 +0000
@@ -17,6 +17,7 @@
17Provide a retry loop that exits on success or an unretryable exception.17Provide a retry loop that exits on success or an unretryable exception.
18"""18"""
19import sys19import sys
20import time
2021
21from utah.exceptions import UTAHException22from utah.exceptions import UTAHException
22from utah.commandstr import commandstr23from utah.commandstr import commandstr
@@ -36,18 +37,24 @@
36 Keyword arguments to be passed to the callable.37 Keyword arguments to be passed to the callable.
3738
38 .. note::39 .. note::
39 If a keyword argument named ``logmethod`` is found, it will be40 There are a few keywords that are consumed by ``retry`` and not
40 extracted (i.e. it won't be passed to the callable) and used to log41 passed to the callable:
41 every retry attempt (using ``sys.stderr`` by default).42 * ``logmethod``: Preferred log method for every retry attempt
43 (``sys.stderr`` by default)
44 * ``retry_timeout``: Timeout in seconds between each retry
45 attempt
46
42 :returns: The value returned by the callable.47 :returns: The value returned by the callable.
4348
44 .. seealso:: :func:`utah.timeout.timeout`49 .. seealso:: :func:`utah.timeout.timeout`
4550
46 """51 """
47 try:52 # The following import is in the function body to avoid a cycle:
48 logmethod = kw.pop('logmethod')53 # utah.config -> utah.url -> utah.retry -> utah.config
49 except KeyError:54 from utah import config
50 logmethod = sys.stderr.write55
56 logmethod = kw.pop('logmethod', sys.stderr.write)
57 retry_timeout = kw.pop('retry_timeout', config.retry_timeout)
51 retval = False58 retval = False
52 while True:59 while True:
53 try:60 try:
@@ -57,8 +64,11 @@
57 try:64 try:
58 if err.retry:65 if err.retry:
59 if logmethod is not None:66 if logmethod is not None:
60 logmethod('Caught ' + str(err) + ', retrying '67 logmethod('Caught {}, retrying {} in {} seconds'
61 + commandstr(command, *args, **kw))68 .format(err,
69 commandstr(command, *args, **kw),
70 retry_timeout))
71 time.sleep(retry_timeout)
62 else:72 else:
63 raise AttributeError73 raise AttributeError
64 except AttributeError:74 except AttributeError:
6575
=== modified file 'utah/url.py'
--- utah/url.py 2013-02-06 10:07:52 +0000
+++ utah/url.py 2013-03-14 17:40:27 +0000
@@ -24,7 +24,6 @@
24import urllib224import urllib2
25import tempfile25import tempfile
26import logging26import logging
27import time
28from urlparse import urlparse27from urlparse import urlparse
29from argparse import ArgumentTypeError28from argparse import ArgumentTypeError
3029
@@ -226,8 +225,6 @@
226 try:225 try:
227 cmd.run(tmp_dir, url)226 cmd.run(tmp_dir, url)
228 except bzrlib.errors.InvalidHttpResponse as exception:227 except bzrlib.errors.InvalidHttpResponse as exception:
229 # Separate every retry attempt with a timeout of 3 seconds
230 time.sleep(3)
231 raise UTAHException(exception.path, exception.msg, retry=True)228 raise UTAHException(exception.path, exception.msg, retry=True)
232229
233 try:230 try:

Subscribers

People subscribed via source and target branches