diff options
author | Soren Hansen <soren@linux2go.dk> | 2011-03-10 20:40:19 +0000 |
---|---|---|
committer | Tarmac <> | 2011-03-10 20:40:19 +0000 |
commit | 7ca1669603132e3afd14606dda3f95ccbce08a41 (patch) | |
tree | aab853348a2df9f5cdb26a77dd836d4f2083f119 /nova/utils.py | |
parent | 044b39e6e7fa81b54cb15176db113ddcc06c4a74 (diff) | |
parent | 11f2d788fd63c66af0e992f7b75b61273c059bcb (diff) | |
download | nova-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.py | 62 |
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, |