Browse Source

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 <chucks@redhat.com>
changes/26/580226/3
Chuck Short 3 years ago
parent
commit
5c1b5cbad7
  1. 41
      cinder/privsep/nvmcli.py
  2. 39
      cinder/privsep/utils.py
  3. 52
      cinder/volume/targets/nvmet.py
  4. 3
      etc/cinder/rootwrap.d/volume.filters

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

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

52
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)
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(
'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
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)

3
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
Loading…
Cancel
Save