summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2012-07-28 03:55:50 +0000
committerGerrit Code Review <review@openstack.org>2012-07-28 03:55:50 +0000
commitcb2bb9f0f60f3fe80ac9cbab832022f925df81b4 (patch)
tree80daacb5e29a7d73ca92a0369cb838f4496e019a
parentebd97be9d6448298811ffccaf30b886ac08bf49f (diff)
parent1ba3dfec786c60e53ceb3b682bcf927224102a0b (diff)
downloadnova-cb2bb9f0f60f3fe80ac9cbab832022f925df81b4.tar.gz
nova-cb2bb9f0f60f3fe80ac9cbab832022f925df81b4.tar.xz
nova-cb2bb9f0f60f3fe80ac9cbab832022f925df81b4.zip
Merge "Add persistent volumes for tgtd."
-rw-r--r--etc/nova/rootwrap.d/volume.filters1
-rw-r--r--nova/tests/test_iscsi.py37
-rw-r--r--nova/volume/driver.py12
-rw-r--r--nova/volume/iscsi.py123
4 files changed, 98 insertions, 75 deletions
diff --git a/etc/nova/rootwrap.d/volume.filters b/etc/nova/rootwrap.d/volume.filters
index 94a621b98..6e68356a0 100644
--- a/etc/nova/rootwrap.d/volume.filters
+++ b/etc/nova/rootwrap.d/volume.filters
@@ -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
diff --git a/nova/tests/test_iscsi.py b/nova/tests/test_iscsi.py
index 1008a9a0c..df619f28c 100644
--- a/nova/tests/test_iscsi.py
+++ b/nova/tests/test_iscsi.py
@@ -28,7 +28,8 @@ 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
@@ -65,11 +66,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 +83,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
+ "/usr/sbin/tgt-admin --conf ./blaa --update blaa",
+ "tgtadm --op show --lld=iscsi --mode=target --tid=1",
+ "/usr/bin/tgt-admin --conf ./blaa --delete blaa"])
class IetAdmTestCase(test.TestCase, TargetAdminTestCase):
@@ -109,8 +98,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"])
diff --git a/nova/volume/driver.py b/nova/volume/driver.py
index 9e8355a3a..7ad070c80 100644
--- a/nova/volume/driver.py
+++ b/nova/volume/driver.py
@@ -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
diff --git a/nova/volume/iscsi.py b/nova/volume/iscsi.py
index 33ee7dabc..b565430d7 100644
--- a/nova/volume/iscsi.py
+++ b/nova/volume/iscsi.py
@@ -19,18 +19,27 @@
Helper code for the iSCSI volume driver.
"""
+import os
+from nova import exception
from nova import flags
from nova.openstack.common import cfg
+from nova.openstack.common import log as logging
from nova import utils
+LOG = logging.getLogger(__name__)
-iscsi_helper_opt = cfg.StrOpt('iscsi_helper',
- default='tgtadm',
- 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,11 +59,19 @@ 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()
@@ -62,11 +79,11 @@ class TargetAdmin(object):
"""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,47 @@ 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 delete_target(self, tid, **kwargs):
- self._run('--op', 'delete',
- '--lld=iscsi', '--mode=target',
- '--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)
+
+ # 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('/usr/sbin/tgt-admin', '--conf %s' % volume_path,
+ '--update %s' % vol_id, run_as_root=True)
+
+ except Exception as ex:
+ LOG.exception(ex)
+ raise exception.NovaException(_('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)
+ volume_path = os.path.join(FLAGS.volumes_dir, vol_id)
+ if os.path.isfile(volume_path):
+ self._execute('/usr/bin/tgt-admin', '--conf %s' % volume_path,
+ '--delete %s' % vol_id, run_as_root_root=True)
+ os.unlink(volume_path)
+ except Exception as ex:
+ LOG.exception(ex)
+ raise exception.NovaException(_('Failed to remove volume: %s')
+ % vol_id)
def show_target(self, tid, **kwargs):
self._run('--op', 'show',
@@ -101,21 +142,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 +149,22 @@ class IetAdm(TargetAdmin):
def __init__(self, execute=utils.execute):
super(IetAdm, self).__init__('ietadm', execute)
- def new_target(self, name, tid, **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 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):
+ def _delete_target(self, tid, **kwargs):
self._run('--op', 'delete',
'--tid=%s' % tid,
**kwargs)
@@ -139,14 +174,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,