diff --git a/etc/rootwrap.conf b/etc/rootwrap.conf new file mode 100644 index 0000000..50e3fca --- /dev/null +++ b/etc/rootwrap.conf @@ -0,0 +1,27 @@ +# Configuration for fuxi-k8s-rootwrap +# This file should be owned by (and only-writable by) the root user + +[DEFAULT] +# List of directories to load filter definitions from (separated by ','). +# These directories MUST all be only writable by root ! +filters_path=/etc/fuxi-kubernetes/rootwrap.d + +# List of directories to search executables in, in case filters do not +# explicitely specify a full path (separated by ',') +# If not specified, defaults to system PATH environment variable. +# These directories MUST all be only writable by root ! +exec_dirs=/sbin,/usr/sbin,/bin,/usr/bin,/usr/local/bin,/usr/local/sbin + +# Enable logging to syslog +# Default value is False +use_syslog=False + +# Which syslog facility to use. +# Valid values include auth, authpriv, syslog, local0, local1... +# Default value is 'syslog' +syslog_log_facility=syslog + +# Which messages to log. +# INFO means log all usage +# ERROR means only log unsuccessful attempts +syslog_log_level=ERROR diff --git a/etc/rootwrap.d/fuxi-kubernetes.filters b/etc/rootwrap.d/fuxi-kubernetes.filters new file mode 100644 index 0000000..37af9f4 --- /dev/null +++ b/etc/rootwrap.d/fuxi-kubernetes.filters @@ -0,0 +1,19 @@ +# fuxi-kubernetes-rootwrap command filters +# This file should be owned by (and only-writeable by) the root user + +[Filters] +# os-brick library commands +# os_brick.privileged.run_as_root oslo.privsep context +# This line ties the superuser privs with the config files, context name, +# and (implicitly) the actual python code invoked. +privsep-rootwrap: RegExpFilter, privsep-helper, root, privsep-helper, --config-file, /etc/(?!\.\.).*, --privsep_context, os_brick.privileged.default, --privsep_sock_path, /tmp/.* + +# The following and any cinder/brick/* entries should all be obsoleted +# by privsep, and may be removed once the os-brick version requirement +# is updated appropriately. +scsi_id: CommandFilter, /lib/udev/scsi_id, root +drbdadm: CommandFilter, drbdadm, root +iscsiadm: CommandFilter, iscsiadm, root +sg_scan: CommandFilter, sg_scan, root +systool: CommandFilter, systool, root +cat: CommandFilter, cat, root diff --git a/fuxi_kubernetes/common/config.py b/fuxi_kubernetes/common/config.py index 4eb44f1..ea7aa16 100644 --- a/fuxi_kubernetes/common/config.py +++ b/fuxi_kubernetes/common/config.py @@ -36,6 +36,10 @@ flexvolume_driver_opts = [ default='baremetal', help=_('The platform on which FlexVolume driver runs. ' 'Optional values are: baremetal')), + cfg.StrOpt('rootwrap_config', + default='/etc/fuxi-kubernetes/rootwrap.conf', + help=_('Path to the rootwrap configuration file to use for ' + 'running commands as root.')), ] diff --git a/fuxi_kubernetes/flex_volume_drivers/server/utils.py b/fuxi_kubernetes/flex_volume_drivers/server/utils.py index ca87043..b65cad1 100644 --- a/fuxi_kubernetes/flex_volume_drivers/server/utils.py +++ b/fuxi_kubernetes/flex_volume_drivers/server/utils.py @@ -12,10 +12,50 @@ from cinderclient import client as cinder_client from kuryr.lib import utils as kuryr_utils +from os_brick.initiator import connector from fuxi_kubernetes.common import config as local_config +def get_root_helper(): + return 'sudo fuxi-k8s-rootwrap %s' % local_config.CONF[ + local_config.flexvolume_driver_group.name].rootwrap_config + + +def brick_get_connector_properties(multipath=False, enforce_multipath=False): + """Wrapper to automatically set root_helper in brick calls. + + :param multipath: A boolean indicating whether the connector can + support multipath. + :param enforce_multipath: If True, it raises exception when multipath=True + is specified but multipathd is not running. + If False, it falls back to multipath=False + when multipathd is not running. + """ + return connector.get_connector_properties( + get_root_helper(), + local_config.CONF[local_config.flexvolume_driver_group.name].node_ip, + multipath, enforce_multipath) + + +def brick_get_connector(protocol, driver=None, use_multipath=False, + device_scan_attempts=3, *args, **kwargs): + """Wrapper to get a brick connector object. + + This automatically populates the required protocol as well + as the root_helper needed to execute commands. + """ + + if protocol.upper() == "RBD": + kwargs['do_local_attach'] = True + + return connector.InitiatorConnector.factory( + protocol, get_root_helper(), + driver=driver, use_multipath=use_multipath, + device_scan_attempts=device_scan_attempts, + *args, **kwargs) + + def _get_keystone_session(conf_group, **kwargs): auth_plugin = kuryr_utils.get_auth_plugin(conf_group) session = kuryr_utils.get_keystone_session(conf_group, auth_plugin) diff --git a/requirements.txt b/requirements.txt index e795375..280ae1f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,6 +4,7 @@ pbr!=2.1.0,>=2.0.0 # Apache-2.0 oslo.serialization>=1.10.0 # Apache-2.0 +os-brick>=1.15.2 # Apache-2.0 python-cinderclient>=3.1.0 # Apache-2.0 stevedore>=1.20.0 # Apache-2.0 Flask!=0.11,<1.0,>=0.10 # BSD diff --git a/setup.cfg b/setup.cfg index ad85cd7..b9577ca 100644 --- a/setup.cfg +++ b/setup.cfg @@ -29,6 +29,7 @@ oslo.config.opts = console_scripts = fuxi-k8s-volume-driver-cinder = fuxi_kubernetes.cmd.cinder:main fuxi-k8s-volume-driver-server = fuxi_kubernetes.cmd.driver_server:main + fuxi-k8s-rootwrap = oslo_rootwrap.cmd:main flex_volume_drivers.server = Cinder = fuxi_kubernetes.flex_volume_drivers.server.cinder.cinder:ServerCinder