diff options
author | Jenkins <jenkins@review.openstack.org> | 2012-07-28 03:55:50 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2012-07-28 03:55:50 +0000 |
commit | cb2bb9f0f60f3fe80ac9cbab832022f925df81b4 (patch) | |
tree | 80daacb5e29a7d73ca92a0369cb838f4496e019a | |
parent | ebd97be9d6448298811ffccaf30b886ac08bf49f (diff) | |
parent | 1ba3dfec786c60e53ceb3b682bcf927224102a0b (diff) | |
download | nova-cb2bb9f0f60f3fe80ac9cbab832022f925df81b4.tar.gz nova-cb2bb9f0f60f3fe80ac9cbab832022f925df81b4.tar.xz nova-cb2bb9f0f60f3fe80ac9cbab832022f925df81b4.zip |
Merge "Add persistent volumes for tgtd."
-rw-r--r-- | etc/nova/rootwrap.d/volume.filters | 1 | ||||
-rw-r--r-- | nova/tests/test_iscsi.py | 37 | ||||
-rw-r--r-- | nova/volume/driver.py | 12 | ||||
-rw-r--r-- | nova/volume/iscsi.py | 123 |
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, |