summaryrefslogtreecommitdiffstats
path: root/nova/utils.py
diff options
context:
space:
mode:
authorSoren Hansen <soren@linux2go.dk>2011-03-10 20:40:19 +0000
committerTarmac <>2011-03-10 20:40:19 +0000
commit7ca1669603132e3afd14606dda3f95ccbce08a41 (patch)
treeaab853348a2df9f5cdb26a77dd836d4f2083f119 /nova/utils.py
parent044b39e6e7fa81b54cb15176db113ddcc06c4a74 (diff)
parent11f2d788fd63c66af0e992f7b75b61273c059bcb (diff)
downloadnova-7ca1669603132e3afd14606dda3f95ccbce08a41.tar.gz
nova-7ca1669603132e3afd14606dda3f95ccbce08a41.tar.xz
nova-7ca1669603132e3afd14606dda3f95ccbce08a41.zip
Add a new IptablesManager that takes care of all uses of iptables.
Port all uses of iptables (in linux_net and libvirt_conn) over to use this new manager. It wraps all uses of iptables so that each component can maintain its own set of rules without interfering with other components and/or existing system rules. iptables-restore is an atomic interface to netfilter in the kernel. This means we can make a bunch of changes at a time, minimising the number of calls to iptables.
Diffstat (limited to 'nova/utils.py')
-rw-r--r--nova/utils.py62
1 files changed, 36 insertions, 26 deletions
diff --git a/nova/utils.py b/nova/utils.py
index 0466fecf4..87e726394 100644
--- a/nova/utils.py
+++ b/nova/utils.py
@@ -139,34 +139,44 @@ def execute(*cmd, **kwargs):
stdin = kwargs.get('stdin', subprocess.PIPE)
stdout = kwargs.get('stdout', subprocess.PIPE)
stderr = kwargs.get('stderr', subprocess.PIPE)
+ attempts = kwargs.get('attempts', 1)
cmd = map(str, cmd)
- LOG.debug(_("Running cmd (subprocess): %s"), ' '.join(cmd))
- env = os.environ.copy()
- if addl_env:
- env.update(addl_env)
- obj = subprocess.Popen(cmd, stdin=stdin,
- stdout=stdout, stderr=stderr, env=env)
- result = None
- if process_input != None:
- result = obj.communicate(process_input)
- else:
- result = obj.communicate()
- obj.stdin.close()
- if obj.returncode:
- LOG.debug(_("Result was %s") % obj.returncode)
- if type(check_exit_code) == types.IntType \
- and obj.returncode != check_exit_code:
- (stdout, stderr) = result
- raise ProcessExecutionError(exit_code=obj.returncode,
- stdout=stdout,
- stderr=stderr,
- cmd=' '.join(cmd))
- # NOTE(termie): this appears to be necessary to let the subprocess call
- # clean something up in between calls, without it two
- # execute calls in a row hangs the second one
- greenthread.sleep(0)
- return result
+ while attempts > 0:
+ attempts -= 1
+ try:
+ LOG.debug(_("Running cmd (subprocess): %s"), ' '.join(cmd))
+ env = os.environ.copy()
+ if addl_env:
+ env.update(addl_env)
+ obj = subprocess.Popen(cmd, stdin=stdin,
+ stdout=stdout, stderr=stderr, env=env)
+ result = None
+ if process_input != None:
+ result = obj.communicate(process_input)
+ else:
+ result = obj.communicate()
+ obj.stdin.close()
+ if obj.returncode:
+ LOG.debug(_("Result was %s") % obj.returncode)
+ if type(check_exit_code) == types.IntType \
+ and obj.returncode != check_exit_code:
+ (stdout, stderr) = result
+ raise ProcessExecutionError(exit_code=obj.returncode,
+ stdout=stdout,
+ stderr=stderr,
+ cmd=' '.join(cmd))
+ # NOTE(termie): this appears to be necessary to let the subprocess
+ # call clean something up in between calls, without
+ # it two execute calls in a row hangs the second one
+ greenthread.sleep(0)
+ return result
+ except ProcessExecutionError:
+ if not attempts:
+ raise
+ else:
+ LOG.debug(_("%r failed. Retrying."), cmd)
+ greenthread.sleep(random.randint(20, 200) / 100.0)
def ssh_execute(ssh, cmd, process_input=None,