From 5c1b5cbad720b3d309152aaa0f54ad0bedb01aac Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Wed, 4 Jul 2018 15:35:37 -0400 Subject: [PATCH] Port nvmet driver to use privsep Now that we have privsep support in cinder, we can start using privsep in various drivers so we can drop rootwrap support. Change-Id: I3cff61b4cde16e00ad23d534c5281a2f1afcd29f Signed-off-by: Chuck Short --- cinder/privsep/nvmcli.py | 41 ++++++++++++++++++++++++ cinder/privsep/utils.py | 39 ++++++++++++++++++++++ cinder/volume/targets/nvmet.py | 48 +++++++++++----------------- etc/cinder/rootwrap.d/volume.filters | 3 -- 4 files changed, 99 insertions(+), 32 deletions(-) create mode 100644 cinder/privsep/nvmcli.py create mode 100644 cinder/privsep/utils.py diff --git a/cinder/privsep/nvmcli.py b/cinder/privsep/nvmcli.py new file mode 100644 index 00000000000..95f5b1c569d --- /dev/null +++ b/cinder/privsep/nvmcli.py @@ -0,0 +1,41 @@ +# Copyright 2018 Red Hat, Inc +# Copyright 2017 Rackspace Australia +# Copyright 2018 Michael Still and Aptira +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +""" +Helpers for nvmetcli related routines. +""" + +from oslo_concurrency import processutils + +import cinder.privsep + + +@cinder.privsep.sys_admin_pctxt.entrypoint +def restore(path): + cmd = [ + 'nvmetcli', + 'restore', + path] + return processutils.execute(*cmd) + + +@cinder.privsep.sys_admin_pctxt.entrypoint +def save(path): + cmd = [ + 'nvmetcli', + 'save', + path] + return processutils.execute(*cmd) diff --git a/cinder/privsep/utils.py b/cinder/privsep/utils.py new file mode 100644 index 00000000000..fc76c6e6c20 --- /dev/null +++ b/cinder/privsep/utils.py @@ -0,0 +1,39 @@ +# Copyright 2018 Red Hat, Inc +# Copyright 2017 Rackspace Australia +# Copyright 2018 Michael Still and Aptira +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +""" +Helpers for cgroup related routines. +""" + +import os + +from cinder import exception +import cinder.privsep + + +@cinder.privsep.sys_admin_pctxt.entrypoint +def readfile(path): + if not os.path.exists(path): + raise exception.FileNotFound(file_path=path) + with open(path, 'r') as f: + return f.read() + + +@cinder.privsep.sys_admin_pctxt.entrypoint +def removefile(path): + if not os.path.exists(path): + raise exception.FileNotFound(file_path=path) + os.unlink(path) diff --git a/cinder/volume/targets/nvmet.py b/cinder/volume/targets/nvmet.py index 58c1485dd00..f8f2b5b9fdc 100644 --- a/cinder/volume/targets/nvmet.py +++ b/cinder/volume/targets/nvmet.py @@ -20,6 +20,7 @@ from oslo_utils import uuidutils import six from cinder import exception +import cinder.privsep from cinder import utils from cinder.volume.targets import nvmeof @@ -76,13 +77,8 @@ class NVMET(nvmeof.NVMeOF): with tempfile.NamedTemporaryFile() as tmp_fd: tmp_fd.write(json.dumps(nvmf_subsystems)) tmp_fd.flush() - cmd = [ - 'nvmetcli', - 'restore', - tmp_fd.name] try: - out, err = utils.execute(*cmd, run_as_root=True) - + out, err = cinder.privsep.nvmcli.restore(tmp_fd.name) except putils.ProcessExecutionError: with excutils.save_and_reraise_exception(): LOG.exception('Error from nvmetcli restore') @@ -156,22 +152,22 @@ class NVMET(nvmeof.NVMeOF): "for volume: %s", volume['id']) def _delete_nvmf_subsystem(self, nvmf_subsystems, subsystem_name): - LOG.debug( - 'Removing this subsystem: %s', subsystem_name) + LOG.debug( + 'Removing this subsystem: %s', subsystem_name) - for port in nvmf_subsystems['ports']: - if subsystem_name in port['subsystems']: - port['subsystems'].remove(subsystem_name) - break - for subsys in nvmf_subsystems['subsystems']: - if subsys['nqn'] == subsystem_name: - nvmf_subsystems['subsystems'].remove(subsys) - break + for port in nvmf_subsystems['ports']: + if subsystem_name in port['subsystems']: + port['subsystems'].remove(subsystem_name) + break + for subsys in nvmf_subsystems['subsystems']: + if subsys['nqn'] == subsystem_name: + nvmf_subsystems['subsystems'].remove(subsys) + break - LOG.debug( - 'Newly loaded subsystems will be: %s', nvmf_subsystems) - self._restore(nvmf_subsystems) - return subsystem_name + LOG.debug( + 'Newly loaded subsystems will be: %s', nvmf_subsystems) + self._restore(nvmf_subsystems) + return subsystem_name def _get_nvmf_subsystem(self, nvmf_subsystems, volume_id): subsystem_name = self._get_target_info( @@ -184,12 +180,8 @@ class NVMET(nvmeof.NVMeOF): __, tmp_file_path = tempfile.mkstemp(prefix='nvmet') # nvmetcli doesn't support printing to stdout yet, - cmd = [ - 'nvmetcli', - 'save', - tmp_file_path] try: - out, err = utils.execute(*cmd, run_as_root=True) + out, err = cinder.privsep.nvmcli.save(tmp_file_path) except putils.ProcessExecutionError: with excutils.save_and_reraise_exception(): LOG.exception('Error from nvmetcli save') @@ -198,9 +190,8 @@ class NVMET(nvmeof.NVMeOF): # temp file must be readable by this process user # in order to avoid executing cat as root with utils.temporary_chown(tmp_file_path): - cmd = ['cat', tmp_file_path] try: - out, err = utils.execute(*cmd) + out = cinder.privsep.utils.readfile(tmp_file_path) except putils.ProcessExecutionError: with excutils.save_and_reraise_exception(): LOG.exception('Failed to read: %s', tmp_file_path) @@ -215,8 +206,7 @@ class NVMET(nvmeof.NVMeOF): return "nqn.%s-%s" % (subsystem, volume_id) def _delete_file(self, file_path): - cmd = ['rm', '-f', file_path] try: - out, err = utils.execute(*cmd, run_as_root=True) + cinder.privsep.utils.removefile(file_path) except putils.ProcessExecutionError: LOG.exception('Failed to delete file: %s', file_path) diff --git a/etc/cinder/rootwrap.d/volume.filters b/etc/cinder/rootwrap.d/volume.filters index 0c6351c3aee..cc751529562 100644 --- a/etc/cinder/rootwrap.d/volume.filters +++ b/etc/cinder/rootwrap.d/volume.filters @@ -230,6 +230,3 @@ drv_cfg: CommandFilter, /opt/emc/scaleio/sdc/bin/drv_cfg, root, /opt/emc/scaleio # cinder/volume/drivers/quobyte.py mount.quobyte: CommandFilter, mount.quobyte, root umount.quobyte: CommandFilter, umount.quobyte, root - -# cinder/volume/targets/nvmet.py -nvmetcli: CommandFilter, nvmetcli, root