Merge "Add persistent volumes for tgtd."
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import os.path
|
||||
import string
|
||||
|
||||
from cinder import test
|
||||
@@ -28,9 +29,12 @@ class TargetAdminTestCase(object):
|
||||
self.tid = 1
|
||||
self.target_name = 'iqn.2011-09.org.foo.bar:blaa'
|
||||
self.lun = 10
|
||||
self.path = '/foo/bar/blaa'
|
||||
self.path = '/foo'
|
||||
self.vol_id = 'blaa'
|
||||
|
||||
self.script_template = None
|
||||
self.stubs.Set(os.path, 'isfile', lambda _: True)
|
||||
self.stubs.Set(os, 'unlink', lambda _: '')
|
||||
|
||||
def get_script_params(self):
|
||||
return {'tid': self.tid,
|
||||
@@ -65,11 +69,10 @@ class TargetAdminTestCase(object):
|
||||
def run_commands(self):
|
||||
tgtadm = iscsi.get_target_admin()
|
||||
tgtadm.set_execute(self.fake_execute)
|
||||
tgtadm.new_target(self.target_name, self.tid)
|
||||
tgtadm.create_iscsi_target(self.target_name, self.tid,
|
||||
self.lun, self.path)
|
||||
tgtadm.show_target(self.tid)
|
||||
tgtadm.new_logicalunit(self.tid, self.lun, self.path)
|
||||
tgtadm.delete_logicalunit(self.tid, self.lun)
|
||||
tgtadm.delete_target(self.tid)
|
||||
tgtadm.remove_iscsi_target(self.tid, self.lun, self.vol_id)
|
||||
|
||||
def test_target_admin(self):
|
||||
self.clear_cmds()
|
||||
@@ -83,22 +86,11 @@ class TgtAdmTestCase(test.TestCase, TargetAdminTestCase):
|
||||
super(TgtAdmTestCase, self).setUp()
|
||||
TargetAdminTestCase.setUp(self)
|
||||
self.flags(iscsi_helper='tgtadm')
|
||||
self.flags(volumes_dir="./")
|
||||
self.script_template = "\n".join([
|
||||
"tgtadm --op new --lld=iscsi --mode=target --tid=%(tid)s "
|
||||
"--targetname=%(target_name)s",
|
||||
"tgtadm --op bind --lld=iscsi --mode=target --initiator-address=ALL "
|
||||
"--tid=%(tid)s",
|
||||
"tgtadm --op show --lld=iscsi --mode=target --tid=%(tid)s",
|
||||
"tgtadm --op new --lld=iscsi --mode=logicalunit --tid=%(tid)s "
|
||||
"--lun=%(lun)d --backing-store=%(path)s",
|
||||
"tgtadm --op delete --lld=iscsi --mode=logicalunit --tid=%(tid)s "
|
||||
"--lun=%(lun)d",
|
||||
"tgtadm --op delete --lld=iscsi --mode=target --tid=%(tid)s"])
|
||||
|
||||
def get_script_params(self):
|
||||
params = super(TgtAdmTestCase, self).get_script_params()
|
||||
params['lun'] += 1
|
||||
return params
|
||||
"tgt-admin --execute --conf ./blaa --update blaa",
|
||||
"tgtadm --op show --lld=iscsi --mode=target --tid=1",
|
||||
"tgt-admin --delete iqn.2010-10.org.openstack:volume-blaa"])
|
||||
|
||||
|
||||
class IetAdmTestCase(test.TestCase, TargetAdminTestCase):
|
||||
@@ -109,8 +101,8 @@ class IetAdmTestCase(test.TestCase, TargetAdminTestCase):
|
||||
self.flags(iscsi_helper='ietadm')
|
||||
self.script_template = "\n".join([
|
||||
"ietadm --op new --tid=%(tid)s --params Name=%(target_name)s",
|
||||
"ietadm --op show --tid=%(tid)s",
|
||||
"ietadm --op new --tid=%(tid)s --lun=%(lun)d "
|
||||
"ietadm --op new --tid=%(tid)s --lun=%(lun)s "
|
||||
"--params Path=%(path)s,Type=fileio",
|
||||
"ietadm --op delete --tid=%(tid)s --lun=%(lun)d",
|
||||
"ietadm --op delete --tid=%(tid)s"])
|
||||
"ietadm --op show --tid=%(tid)s",
|
||||
"ietadm --op delete --tid=%(tid)s",
|
||||
"ietadm --op delete --tid=%(tid)s --lun=%(lun)s"])
|
||||
|
||||
@@ -274,9 +274,8 @@ class ISCSIDriver(VolumeDriver):
|
||||
iscsi_name = "%s%s" % (FLAGS.iscsi_target_prefix, volume['name'])
|
||||
volume_path = "/dev/%s/%s" % (FLAGS.volume_group, volume['name'])
|
||||
|
||||
self.tgtadm.new_target(iscsi_name, iscsi_target, check_exit_code=False)
|
||||
self.tgtadm.new_logicalunit(iscsi_target, 0, volume_path,
|
||||
check_exit_code=False)
|
||||
self.tgtadm.create_iscsi_target(iscsi_name, iscsi_target,
|
||||
0, volume_path, check_exit_code=False)
|
||||
|
||||
def _ensure_iscsi_targets(self, context, host):
|
||||
"""Ensure that target ids have been created in datastore."""
|
||||
@@ -297,8 +296,8 @@ class ISCSIDriver(VolumeDriver):
|
||||
iscsi_name = "%s%s" % (FLAGS.iscsi_target_prefix, volume['name'])
|
||||
volume_path = "/dev/%s/%s" % (FLAGS.volume_group, volume['name'])
|
||||
|
||||
self.tgtadm.new_target(iscsi_name, iscsi_target)
|
||||
self.tgtadm.new_logicalunit(iscsi_target, 0, volume_path)
|
||||
self.tgtadm.create_iscsi_target(iscsi_name, iscsi_target,
|
||||
0, volume_path)
|
||||
|
||||
model_update = {}
|
||||
if FLAGS.iscsi_helper == 'tgtadm':
|
||||
@@ -328,8 +327,7 @@ class ISCSIDriver(VolumeDriver):
|
||||
"is presently exported for volume: %s"), volume['id'])
|
||||
return
|
||||
|
||||
self.tgtadm.delete_logicalunit(iscsi_target, 0)
|
||||
self.tgtadm.delete_target(iscsi_target)
|
||||
self.tgtadm.remove_iscsi_target(iscsi_target, 0, volume['id'])
|
||||
|
||||
def _do_iscsi_discovery(self, volume):
|
||||
#TODO(justinsb): Deprecate discovery and use stored info
|
||||
|
||||
@@ -19,18 +19,27 @@
|
||||
Helper code for the iSCSI volume driver.
|
||||
|
||||
"""
|
||||
import os
|
||||
|
||||
from cinder import exception
|
||||
from cinder import flags
|
||||
from cinder.openstack.common import cfg
|
||||
from cinder.openstack.common import log as logging
|
||||
from cinder import utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
iscsi_helper_opt = cfg.StrOpt('iscsi_helper',
|
||||
default='ietadm',
|
||||
help='iscsi target user-land tool to use')
|
||||
iscsi_helper_opt = [
|
||||
cfg.StrOpt('iscsi_helper',
|
||||
default='tgtadm',
|
||||
help='iscsi target user-land tool to use'),
|
||||
cfg.StrOpt('volumes_dir',
|
||||
default='$state_path/volumes',
|
||||
help='Volume configfuration file storage directory'),
|
||||
]
|
||||
|
||||
FLAGS = flags.FLAGS
|
||||
FLAGS.register_opt(iscsi_helper_opt)
|
||||
FLAGS.register_opts(iscsi_helper_opt)
|
||||
|
||||
|
||||
class TargetAdmin(object):
|
||||
@@ -50,23 +59,31 @@ class TargetAdmin(object):
|
||||
def _run(self, *args, **kwargs):
|
||||
self._execute(self._cmd, *args, run_as_root=True, **kwargs)
|
||||
|
||||
def new_target(self, name, tid, **kwargs):
|
||||
def create_iscsi_target(self, name, tid, lun, path, **kwargs):
|
||||
"""Create a iSCSI target and logical unit"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def remove_iscsi_target(self, tid, lun, vol_id, **kwargs):
|
||||
"""Remove a iSCSI target and logical unit"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def _new_target(self, name, tid, **kwargs):
|
||||
"""Create a new iSCSI target."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def delete_target(self, tid, **kwargs):
|
||||
def _delete_target(self, tid, **kwargs):
|
||||
"""Delete a target."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def show_target(self, tid, **kwargs):
|
||||
def _show_target(self, tid, **kwargs):
|
||||
"""Query the given target ID."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def new_logicalunit(self, tid, lun, path, **kwargs):
|
||||
def _new_logicalunit(self, tid, lun, path, **kwargs):
|
||||
"""Create a new LUN on a target using the supplied path."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def delete_logicalunit(self, tid, lun, **kwargs):
|
||||
def _delete_logicalunit(self, tid, lun, **kwargs):
|
||||
"""Delete a logical unit from a target."""
|
||||
raise NotImplementedError()
|
||||
|
||||
@@ -77,23 +94,53 @@ class TgtAdm(TargetAdmin):
|
||||
def __init__(self, execute=utils.execute):
|
||||
super(TgtAdm, self).__init__('tgtadm', execute)
|
||||
|
||||
def new_target(self, name, tid, **kwargs):
|
||||
self._run('--op', 'new',
|
||||
'--lld=iscsi', '--mode=target',
|
||||
'--tid=%s' % tid,
|
||||
'--targetname=%s' % name,
|
||||
**kwargs)
|
||||
self._run('--op', 'bind',
|
||||
'--lld=iscsi', '--mode=target',
|
||||
'--initiator-address=ALL',
|
||||
'--tid=%s' % tid,
|
||||
**kwargs)
|
||||
def create_iscsi_target(self, name, tid, lun, path, **kwargs):
|
||||
try:
|
||||
if not os.path.exists(FLAGS.volumes_dir):
|
||||
os.makedirs(FLAGS.volumes_dir)
|
||||
|
||||
def delete_target(self, tid, **kwargs):
|
||||
self._run('--op', 'delete',
|
||||
'--lld=iscsi', '--mode=target',
|
||||
'--tid=%s' % tid,
|
||||
**kwargs)
|
||||
# grab the volume id
|
||||
vol_id = name.split(':')[1]
|
||||
|
||||
volume_conf = """
|
||||
<target %s>
|
||||
backing-store %s
|
||||
</target>
|
||||
""" % (name, path)
|
||||
|
||||
LOG.info(_('Creating volume: %s') % vol_id)
|
||||
volume_path = os.path.join(FLAGS.volumes_dir, vol_id)
|
||||
if not os.path.isfile(volume_path):
|
||||
f = open(volume_path, 'w+')
|
||||
f.write(volume_conf)
|
||||
f.close()
|
||||
|
||||
self._execute('tgt-admin', '--execute',
|
||||
'--conf %s' % volume_path,
|
||||
'--update %s' % vol_id, run_as_root=True)
|
||||
|
||||
except Exception as ex:
|
||||
LOG.exception(ex)
|
||||
raise exception.Error(_('Failed to create volume: %s')
|
||||
% vol_id)
|
||||
|
||||
def remove_iscsi_target(self, tid, lun, vol_id, **kwargs):
|
||||
try:
|
||||
LOG.info(_('Removing volume: %s') % vol_id)
|
||||
vol_uuid_file = 'volume-%s' % vol_id
|
||||
volume_path = os.path.join(FLAGS.volumes_dir, vol_uuid_file)
|
||||
if os.path.isfile(volume_path):
|
||||
delete_file = '%s%s' % (FLAGS.iscsi_target_prefix,
|
||||
vol_uuid_file)
|
||||
self._execute('tgt-admin',
|
||||
'--delete',
|
||||
delete_file,
|
||||
run_as_root=True)
|
||||
os.unlink(volume_path)
|
||||
except Exception as ex:
|
||||
LOG.exception(ex)
|
||||
raise exception.Error(_('Failed to remove volume: %s')
|
||||
% vol_id)
|
||||
|
||||
def show_target(self, tid, **kwargs):
|
||||
self._run('--op', 'show',
|
||||
@@ -101,21 +148,6 @@ class TgtAdm(TargetAdmin):
|
||||
'--tid=%s' % tid,
|
||||
**kwargs)
|
||||
|
||||
def new_logicalunit(self, tid, lun, path, **kwargs):
|
||||
self._run('--op', 'new',
|
||||
'--lld=iscsi', '--mode=logicalunit',
|
||||
'--tid=%s' % tid,
|
||||
'--lun=%d' % (lun + 1), # lun0 is reserved
|
||||
'--backing-store=%s' % path,
|
||||
**kwargs)
|
||||
|
||||
def delete_logicalunit(self, tid, lun, **kwargs):
|
||||
self._run('--op', 'delete',
|
||||
'--lld=iscsi', '--mode=logicalunit',
|
||||
'--tid=%s' % tid,
|
||||
'--lun=%d' % (lun + 1),
|
||||
**kwargs)
|
||||
|
||||
|
||||
class IetAdm(TargetAdmin):
|
||||
"""iSCSI target administration using ietadm."""
|
||||
@@ -123,13 +155,22 @@ class IetAdm(TargetAdmin):
|
||||
def __init__(self, execute=utils.execute):
|
||||
super(IetAdm, self).__init__('ietadm', execute)
|
||||
|
||||
def new_target(self, name, tid, **kwargs):
|
||||
self._run('--op', 'new',
|
||||
'--tid=%s' % tid,
|
||||
'--params', 'Name=%s' % name,
|
||||
**kwargs)
|
||||
def create_iscsi_target(self, name, tid, lun, path, **kwargs):
|
||||
self._new_target(name, tid, **kwargs)
|
||||
self._new_logicalunit(tid, lun, path, **kwargs)
|
||||
|
||||
def delete_target(self, tid, **kwargs):
|
||||
def remove_iscsi_target(self, tid, lun, vol_id, **kwargs):
|
||||
LOG.info(_('Removing volume: %s') % vol_id)
|
||||
self._delete_target(tid, **kwargs)
|
||||
self._delete_logicalunit(tid, lun, **kwargs)
|
||||
|
||||
def _new_target(self, name, tid, **kwargs):
|
||||
self._run('--op', 'new',
|
||||
'--tid=%s' % tid,
|
||||
'--params', 'Name=%s' % name,
|
||||
**kwargs)
|
||||
|
||||
def _delete_target(self, tid, **kwargs):
|
||||
self._run('--op', 'delete',
|
||||
'--tid=%s' % tid,
|
||||
**kwargs)
|
||||
@@ -139,14 +180,14 @@ class IetAdm(TargetAdmin):
|
||||
'--tid=%s' % tid,
|
||||
**kwargs)
|
||||
|
||||
def new_logicalunit(self, tid, lun, path, **kwargs):
|
||||
def _new_logicalunit(self, tid, lun, path, **kwargs):
|
||||
self._run('--op', 'new',
|
||||
'--tid=%s' % tid,
|
||||
'--lun=%d' % lun,
|
||||
'--params', 'Path=%s,Type=fileio' % path,
|
||||
**kwargs)
|
||||
|
||||
def delete_logicalunit(self, tid, lun, **kwargs):
|
||||
def _delete_logicalunit(self, tid, lun, **kwargs):
|
||||
self._run('--op', 'delete',
|
||||
'--tid=%s' % tid,
|
||||
'--lun=%d' % lun,
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
# nova/volume/iscsi.py: iscsi_helper '--op' ...
|
||||
ietadm: CommandFilter, /usr/sbin/ietadm, root
|
||||
tgtadm: CommandFilter, /usr/sbin/tgtadm, root
|
||||
tgt-admin: CommandFilter, /usr/sbin/tgt-admin, root
|
||||
|
||||
# nova/volume/driver.py: 'vgs', '--noheadings', '-o', 'name'
|
||||
vgs: CommandFilter, /sbin/vgs, root
|
||||
|
||||
Reference in New Issue
Block a user