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:
Yuriy Taraday 2014-07-15 18:27:54 +04:00
parent 196bdc0fa2
commit e6c39e8370
3 changed files with 50 additions and 41 deletions

View File

@ -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)"

View File

@ -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

View File

@ -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)