Refactor common parts from cmd to wrapper
This is needed to allow daemon reuse these parts and be plugged in clearly. Change-Id: I01e020ae6f185faa446c715cf9a6b0c082260e13
This commit is contained in:
parent
196bdc0fa2
commit
e6c39e8370
@ -33,10 +33,6 @@
|
||||
from __future__ import print_function
|
||||
|
||||
import logging
|
||||
import os
|
||||
import pwd
|
||||
import signal
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from six import moves
|
||||
@ -49,12 +45,6 @@ RC_BADCONFIG = 97
|
||||
RC_NOEXECFOUND = 96
|
||||
|
||||
|
||||
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 _exit_error(execname, message, errorcode, log=True):
|
||||
print("%s: %s" % (execname, message), file=sys.stderr)
|
||||
if log:
|
||||
@ -62,15 +52,6 @@ def _exit_error(execname, message, errorcode, log=True):
|
||||
sys.exit(errorcode)
|
||||
|
||||
|
||||
def _getlogin():
|
||||
try:
|
||||
return os.getlogin()
|
||||
except OSError:
|
||||
return (os.getenv('USER') or
|
||||
os.getenv('USERNAME') or
|
||||
os.getenv('LOGNAME'))
|
||||
|
||||
|
||||
def main():
|
||||
# Split arguments, require at least a command
|
||||
execname = sys.argv.pop(0)
|
||||
@ -97,27 +78,22 @@ def main():
|
||||
config.syslog_log_facility,
|
||||
config.syslog_log_level)
|
||||
|
||||
# Execute command if it matches any of the loaded filters
|
||||
filters = wrapper.load_filters(config.filters_path)
|
||||
try:
|
||||
filtermatch = wrapper.match_filter(filters, userargs,
|
||||
exec_dirs=config.exec_dirs)
|
||||
if filtermatch:
|
||||
command = filtermatch.get_command(userargs,
|
||||
exec_dirs=config.exec_dirs)
|
||||
if config.use_syslog:
|
||||
logging.info("(%s > %s) Executing %s (filter match = %s)" % (
|
||||
_getlogin(), pwd.getpwuid(os.getuid())[0],
|
||||
command, filtermatch.name))
|
||||
run_one_command(execname, config, filters, userargs)
|
||||
|
||||
obj = subprocess.Popen(command,
|
||||
stdin=sys.stdin,
|
||||
stdout=sys.stdout,
|
||||
stderr=sys.stderr,
|
||||
preexec_fn=_subprocess_setup,
|
||||
env=filtermatch.get_environment(userargs))
|
||||
obj.wait()
|
||||
sys.exit(obj.returncode)
|
||||
|
||||
def run_one_command(execname, config, filters, userargs):
|
||||
# Execute command if it matches any of the loaded filters
|
||||
try:
|
||||
obj = wrapper.start_subprocess(
|
||||
filters, userargs,
|
||||
exec_dirs=config.exec_dirs,
|
||||
log=config.use_syslog,
|
||||
stdin=sys.stdin,
|
||||
stdout=sys.stdout,
|
||||
stderr=sys.stderr)
|
||||
obj.wait()
|
||||
sys.exit(obj.returncode)
|
||||
|
||||
except wrapper.FilterMatchNotExecutable as exc:
|
||||
msg = ("Executable not found: %s (filter match = %s)"
|
||||
|
@ -16,6 +16,9 @@
|
||||
import logging
|
||||
import logging.handlers
|
||||
import os
|
||||
import pwd
|
||||
import signal
|
||||
import subprocess
|
||||
|
||||
from six import moves
|
||||
|
||||
@ -170,3 +173,34 @@ def match_filter(filter_list, userargs, exec_dirs=None):
|
||||
|
||||
# No filter matched
|
||||
raise NoFilterMatched()
|
||||
|
||||
|
||||
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 _getlogin():
|
||||
try:
|
||||
return os.getlogin()
|
||||
except OSError:
|
||||
return (os.getenv('USER') or
|
||||
os.getenv('USERNAME') or
|
||||
os.getenv('LOGNAME'))
|
||||
|
||||
|
||||
def start_subprocess(filter_list, userargs, exec_dirs=[], log=False, **kwargs):
|
||||
filtermatch = match_filter(filter_list, userargs, exec_dirs)
|
||||
|
||||
command = filtermatch.get_command(userargs, exec_dirs)
|
||||
if log:
|
||||
logging.info("(%s > %s) Executing %s (filter match = %s)" % (
|
||||
_getlogin(), pwd.getpwuid(os.getuid())[0],
|
||||
command, filtermatch.name))
|
||||
|
||||
obj = subprocess.Popen(command,
|
||||
preexec_fn=_subprocess_setup,
|
||||
env=filtermatch.get_environment(userargs),
|
||||
**kwargs)
|
||||
return obj
|
||||
|
@ -23,7 +23,6 @@ import mock
|
||||
from six import moves
|
||||
import testtools
|
||||
|
||||
from oslo.rootwrap import cmd
|
||||
from oslo.rootwrap import filters
|
||||
from oslo.rootwrap import wrapper
|
||||
|
||||
@ -437,7 +436,7 @@ class RootwrapTestCase(testtools.TestCase):
|
||||
def test_getlogin(self):
|
||||
with mock.patch('os.getlogin') as os_getlogin:
|
||||
os_getlogin.return_value = 'foo'
|
||||
self.assertEqual(cmd._getlogin(), 'foo')
|
||||
self.assertEqual(wrapper._getlogin(), 'foo')
|
||||
|
||||
def test_getlogin_bad(self):
|
||||
with mock.patch('os.getenv') as os_getenv:
|
||||
@ -445,7 +444,7 @@ class RootwrapTestCase(testtools.TestCase):
|
||||
os_getenv.side_effect = [None, None, 'bar']
|
||||
os_getlogin.side_effect = OSError(
|
||||
'[Errno 22] Invalid argument')
|
||||
self.assertEqual(cmd._getlogin(), 'bar')
|
||||
self.assertEqual(wrapper._getlogin(), 'bar')
|
||||
os_getlogin.assert_called_once_with()
|
||||
self.assertEqual(os_getenv.call_count, 3)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user