summaryrefslogtreecommitdiffstats
path: root/nova/utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'nova/utils.py')
-rw-r--r--nova/utils.py123
1 files changed, 14 insertions, 109 deletions
diff --git a/nova/utils.py b/nova/utils.py
index bb002b9e7..64606f4f8 100644
--- a/nova/utils.py
+++ b/nova/utils.py
@@ -30,7 +30,6 @@ import pyclbr
import random
import re
import shutil
-import signal
import socket
import struct
import sys
@@ -38,8 +37,6 @@ import tempfile
import time
from xml.sax import saxutils
-from eventlet.green import subprocess
-from eventlet import greenthread
import netaddr
from oslo.config import cfg
@@ -48,6 +45,7 @@ from nova import exception
from nova.openstack.common import excutils
from nova.openstack.common import importutils
from nova.openstack.common import log as logging
+from nova.openstack.common import processutils
from nova.openstack.common.rpc import common as rpc_common
from nova.openstack.common import timeutils
@@ -149,107 +147,11 @@ def vpn_ping(address, port, timeout=0.05, session_id=None):
return server_sess
-def _subprocess_setup():
- # Python installs a SIGPIPE handler by default. This is usually not what
- # non-Python subprocesses expect.
- signal.signal(signal.SIGPIPE, signal.SIG_DFL)
-
-
def execute(*cmd, **kwargs):
- """Helper method to execute command with optional retry.
-
- If you add a run_as_root=True command, don't forget to add the
- corresponding filter to etc/nova/rootwrap.d !
-
- :param cmd: Passed to subprocess.Popen.
- :param process_input: Send to opened process.
- :param check_exit_code: Single bool, int, or list of allowed exit
- codes. Defaults to [0]. Raise
- exception.ProcessExecutionError unless
- program exits with one of these code.
- :param delay_on_retry: True | False. Defaults to True. If set to
- True, wait a short amount of time
- before retrying.
- :param attempts: How many times to retry cmd.
- :param run_as_root: True | False. Defaults to False. If set to True,
- the command is run with rootwrap.
-
- :raises exception.NovaException: on receiving unknown arguments
- :raises exception.ProcessExecutionError:
-
- :returns: a tuple, (stdout, stderr) from the spawned process, or None if
- the command fails.
- """
- process_input = kwargs.pop('process_input', None)
- check_exit_code = kwargs.pop('check_exit_code', [0])
- ignore_exit_code = False
- if isinstance(check_exit_code, bool):
- ignore_exit_code = not check_exit_code
- check_exit_code = [0]
- elif isinstance(check_exit_code, int):
- check_exit_code = [check_exit_code]
- delay_on_retry = kwargs.pop('delay_on_retry', True)
- attempts = kwargs.pop('attempts', 1)
- run_as_root = kwargs.pop('run_as_root', False)
- shell = kwargs.pop('shell', False)
-
- if len(kwargs):
- raise exception.NovaException(_('Got unknown keyword args '
- 'to utils.execute: %r') % kwargs)
-
- if run_as_root and os.geteuid() != 0:
- cmd = ['sudo', 'nova-rootwrap', CONF.rootwrap_config] + list(cmd)
-
- cmd = map(str, cmd)
-
- while attempts > 0:
- attempts -= 1
- try:
- LOG.debug(_('Running cmd (subprocess): %s'), ' '.join(cmd))
- _PIPE = subprocess.PIPE # pylint: disable=E1101
-
- if os.name == 'nt':
- preexec_fn = None
- close_fds = False
- else:
- preexec_fn = _subprocess_setup
- close_fds = True
-
- obj = subprocess.Popen(cmd,
- stdin=_PIPE,
- stdout=_PIPE,
- stderr=_PIPE,
- close_fds=close_fds,
- preexec_fn=preexec_fn,
- shell=shell)
- result = None
- if process_input is not None:
- result = obj.communicate(process_input)
- else:
- result = obj.communicate()
- obj.stdin.close() # pylint: disable=E1101
- _returncode = obj.returncode # pylint: disable=E1101
- LOG.debug(_('Result was %s') % _returncode)
- if not ignore_exit_code and _returncode not in check_exit_code:
- (stdout, stderr) = result
- raise exception.ProcessExecutionError(
- exit_code=_returncode,
- stdout=stdout,
- stderr=stderr,
- cmd=' '.join(cmd))
- return result
- except exception.ProcessExecutionError:
- if not attempts:
- raise
- else:
- LOG.debug(_('%r failed. Retrying.'), cmd)
- if delay_on_retry:
- greenthread.sleep(random.randint(20, 200) / 100.0)
- finally:
- # 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)
+ """Convenience wrapper around oslo's execute() method."""
+ if 'run_as_root' in kwargs and not 'root_helper' in kwargs:
+ kwargs['root_helper'] = 'sudo nova-rootwrap %s' % CONF.rootwrap_config
+ return processutils.execute(*cmd, **kwargs)
def trycmd(*args, **kwargs):
@@ -269,7 +171,7 @@ def trycmd(*args, **kwargs):
try:
out, err = execute(*args, **kwargs)
failed = False
- except exception.ProcessExecutionError, exn:
+ except processutils.ProcessExecutionError, exn:
out, err = '', str(exn)
failed = True
@@ -309,10 +211,13 @@ def ssh_execute(ssh, cmd, process_input=None,
if exit_status != -1:
LOG.debug(_('Result was %s') % exit_status)
if check_exit_code and exit_status != 0:
- raise exception.ProcessExecutionError(exit_code=exit_status,
- stdout=stdout,
- stderr=stderr,
- cmd=cmd)
+ # TODO(mikal): I know this is a bit odd, but its needed for
+ # consistency. I will move this method into processutils in a
+ # later change.
+ raise processutils.ProcessExecutionError(exit_code=exit_status,
+ stdout=stdout,
+ stderr=stderr,
+ cmd=cmd)
return (stdout, stderr)
@@ -1066,7 +971,7 @@ def read_file_as_root(file_path):
try:
out, _err = execute('cat', file_path, run_as_root=True)
return out
- except exception.ProcessExecutionError:
+ except processutils.ProcessExecutionError:
raise exception.FileNotFound(file_path=file_path)