First attempt at adding a privsep user to nova itself.

I don't particularly care about this use case (although the localfs
code should perhaps go away), but it was a nice contained example
of a privsep user which wasn't just calling a command line.

This patch also starts to layout what an API to the privsep'd code
might look like. For now its modelled on python's os module, because
that's where all the operations we perform are coming from.

The rootwrap configuration is cleaned up as we remove users.

Co-Authored-By: Tony Breeds <tony@bakeyournoodle.com>
Change-Id: I911cc51a226d6af29d63a7a2c69253de870073e9
This commit is contained in:
Michael Still 2017-04-24 14:51:42 +10:00
parent 7930d25422
commit 72d262a368
3 changed files with 30 additions and 9 deletions

@ -313,6 +313,9 @@ class TestCase(testtools.TestCase):
self.useFixture(nova_fixtures.ForbidNewLegacyNotificationFixture())
# NOTE(mikal): make sure we don't load a privsep helper accidentally
self.useFixture(nova_fixtures.PrivsepNoHelperFixture())
def _setup_cells(self):
"""Setup a normal cellsv2 environment.

@ -30,6 +30,7 @@ from oslo_concurrency import lockutils
from oslo_config import cfg
import oslo_messaging as messaging
from oslo_messaging import conffixture as messaging_conffixture
from oslo_privsep import daemon as privsep_daemon
from requests import adapters
from wsgi_intercept import interceptor
@ -1538,3 +1539,29 @@ class PlacementFixture(fixtures.Fixture):
endpoint_override=self.endpoint,
headers={'x-auth-token': self.token},
raise_exc=False)
class UnHelperfulClientChannel(privsep_daemon._ClientChannel):
def __init__(self, context):
raise Exception('You have attempted to start a privsep helper. '
'This is not allowed in the gate, and '
'indicates a failure to have mocked your tests.')
class PrivsepNoHelperFixture(fixtures.Fixture):
"""A fixture to catch failures to mock privsep's rootwrap helper.
If you fail to mock away a privsep'd method in a unit test, then
you may well end up accidentally running the privsep rootwrap
helper. This will fail in the gate, but it fails in a way which
doesn't identify which test is missing a mock. Instead, we
raise an exception so that you at least know where you've missed
something.
"""
def setUp(self):
super(PrivsepNoHelperFixture, self).setUp()
self.useFixture(fixtures.MonkeyPatch(
'oslo_privsep.daemon.RootwrapClientChannel',
UnHelperfulClientChannel))

@ -666,15 +666,6 @@ def generate_mac_address():
return ':'.join(map(lambda x: "%02x" % x, mac))
def read_file_as_root(file_path):
"""Secure helper to read file as root."""
try:
out, _err = execute('cat', file_path, run_as_root=True)
return out
except processutils.ProcessExecutionError:
raise exception.FileNotFound(file_path=file_path)
@contextlib.contextmanager
def temporary_chown(path, owner_uid=None):
"""Temporarily chown a path.