Пример #1
0
    def test_extend_lun(self):

        jrest, ctx = self.get_rest(CONFIG_OK)
        resp = {'data': None,
                'error': None,
                'code': 201}

        jbody = {
            'size': "2147483648",
        }

        jrest.rproxy.pool_request.return_value = resp
        self.assertIsNone(jrest.extend_lun(jcom.vname(UUID_1), 2 * o_units.Gi))

        err = {'message': 'test failure'}
        resp = {'code': 500,
                'data': None,
                'error': err}
        jrest.rproxy.pool_request.return_value = resp
        self.assertRaises(jexc.JDSSRESTException,
                          jrest.extend_lun,
                          jcom.vname(UUID_1),
                          2 * o_units.Gi)

        addr = "/volumes/" + jcom.vname(UUID_1)
        create_lun_expected = [
            mock.call('PUT', addr, json_data=jbody),
            mock.call('PUT', addr, json_data=jbody)]

        jrest.rproxy.pool_request.assert_has_calls(create_lun_expected)
Пример #2
0
    def test_gc_delete_not_clone(self):

        jdssd, ctx = self.get_driver(CONFIG_OK)
        vol = fake_volume.fake_volume_obj(ctx)
        vol.id = UUID_1

        get_lun_resp = {
            'vscan': None,
            'full_name': 'Pool-0/' + jcom.vname(UUID_1),
            'userrefs': None,
            'primarycache': 'all',
            'logbias': 'latency',
            'creation': '1591543140',
            'sync': 'always',
            'is_clone': False,
            'dedup': 'off',
            'sharenfs': None,
            'receive_resume_token': None,
            'volsize': '1073741824'
        }

        jdssd.ra.get_lun.return_value = get_lun_resp
        jdssd.ra.delete_lun.return_value = None

        patches = [mock.patch.object(jdssd, "_delete_back_recursively")]

        self.start_patches(patches)

        jdssd._gc_delete(jcom.vname(UUID_1))

        jdssd._delete_back_recursively.assert_not_called()
        jdssd.ra.delete_lun.assert_called_once_with(jcom.vname(UUID_1))

        self.stop_patches(patches)
Пример #3
0
    def create_cloned_volume(self, volume, src_vref):
        """Create a clone of the specified volume.

        :param volume: new volume reference
        :param src_vref: source volume reference
        """
        cvname = jcom.vname(volume.id)

        vname = jcom.vname(src_vref.id)

        LOG.debug('cloned volume %(id)s to %(id_clone)s', {
            "id": src_vref.id,
            "id_clone": volume.id
        })

        self._clone_object(vname, cvname)

        clone_size = 0

        try:
            clone_size = int(self.ra.get_lun(cvname)['volsize'])
        except jexc.JDSSException as jerr:

            self._delete_back_recursively(vname, cvname)
            raise exception.VolumeBackendAPIException(
                _("Fail in cloning volume %(vol)s to %(clone)s.") % {
                    'vol': src_vref.id,
                    'clone': volume.id
                }) from jerr

        try:
            if int(clone_size) < o_units.Gi * int(volume.size):
                self.extend_volume(volume, int(volume.size))

        except exception.VolumeBackendAPIException:
            # If volume can't be set to a proper size make sure to clean it
            # before failing
            try:
                self._delete_back_recursively(cvname, cvname)
            except exception.VolumeBackendAPIException as err:
                LOG.warning(
                    "Because of %s physical snapshot %s of volume"
                    " %s have to be removed manually", err, cvname, vname)
            raise

        provider_location = self._get_provider_location(volume.id)
        provider_auth = self._get_provider_auth()

        ret = {}
        if provider_auth:
            ret['provider_auth'] = provider_auth

        ret['provider_location'] = provider_location

        return ret
Пример #4
0
    def test_clone_object(self):
        jdssd, ctx = self.get_driver(CONFIG_OK)
        origin = jcom.vname(UUID_1)
        clone = jcom.vname(UUID_2)

        jdssd.ra.create_snapshot.return_value = None
        jdssd.ra.create_volume_from_snapshot.return_value = None

        jdssd._clone_object(origin, clone)
        jdssd.ra.create_snapshot.assert_called_once_with(origin, clone)
        jdssd.ra.create_volume_from_snapshot.assert_called_once_with(
            clone, clone, origin, sparse=False)
Пример #5
0
    def test_create_lun(self):

        jrest, ctx = self.get_rest(CONFIG_OK)
        resp = {'data': {
                'vscan': None,
                'full_name': 'pool-0/' + jcom.vname(UUID_1),
                'userrefs': None,
                'primarycache': 'all',
                'logbias': 'latency',
                'creation': '1591543140',
                'sync': 'always',
                'is_clone': False,
                'dedup': 'off',
                'sharenfs': None,
                'receive_resume_token': None,
                'volsize': '1073741824'},
                'error': None,
                'code': 200}

        jbody = {
            'name': jcom.vname(UUID_1),
            'size': "1073741824",
            'sparse': False
        }

        jbody_sparse = {
            'name': jcom.vname(UUID_1),
            'size': "1073741824",
            'sparse': True
        }

        jrest.rproxy.pool_request.return_value = resp
        self.assertIsNone(jrest.create_lun(jcom.vname(UUID_1), o_units.Gi))

        err = {'errno': '5', 'message': 'test failure'}
        resp = {'code': 404,
                'data': None,
                'error': err}
        jrest.rproxy.pool_request.return_value = resp
        self.assertRaises(jexc.JDSSRESTException,
                          jrest.create_lun,
                          jcom.vname(UUID_1),
                          o_units.Gi,
                          sparse=True)

        addr = "/volumes"
        create_lun_expected = [
            mock.call('POST', addr, json_data=jbody),
            mock.call('POST', addr, json_data=jbody_sparse)]

        jrest.rproxy.pool_request.assert_has_calls(create_lun_expected)
Пример #6
0
    def test_clone_object_volume_exists(self):
        jdssd, ctx = self.get_driver(CONFIG_OK)

        origin = jcom.vname(UUID_1)
        clone = jcom.vname(UUID_2)

        jdssd.ra.create_snapshot.return_value = None
        jdssd.ra.create_volume_from_snapshot.side_effect = (
            jexc.JDSSVolumeExistsException(volume=clone))

        self.assertRaises(exception.Duplicate, jdssd._clone_object, origin,
                          clone)
        jdssd.ra.create_snapshot.assert_called_once_with(origin, clone)
        jdssd.ra.create_volume_from_snapshot.assert_called_once_with(
            clone, clone, origin, sparse=CONFIG_OK['san_thin_provision'])
Пример #7
0
    def test_cascade_volume_delete_with_clone(self):
        # Volume with 2 snapshots and 1 clone
        # We should delete snapshots and then cal for volume hiding
        jdssd, ctx = self.get_driver(CONFIG_OK)
        o_vname = jcom.vname(UUID_1)
        o_snaps = SNAPSHOTS_CASCADE_2.copy()

        jdssd.ra.modify_lun.return_value = None
        jdssd.ra.delete_snapshot.return_value = None
        jdssd.ra.get_snapshots.side_effect = [SNAPSHOTS_EMPTY, SNAPSHOTS_EMPTY]

        fake_gc = mock.Mock()
        fake_hide_object = mock.Mock()
        gc = mock.patch.object(jdssd, "_gc_delete", new=fake_gc)
        gc.start()
        hide = mock.patch.object(jdssd, "_hide_object", new=fake_hide_object)
        hide.start()
        jdssd._cascade_volume_delete(o_vname, o_snaps)
        jdssd._hide_object.assert_called_once_with(o_vname)
        hide.stop()
        jdssd._gc_delete.assert_not_called()
        gc.stop()
        delete_snapshot_expected = [
            mock.call(o_vname,
                      SNAPSHOTS_CASCADE_2[0]["name"],
                      recursively_children=True,
                      recursively_dependents=True,
                      force_umount=True),
            mock.call(o_vname,
                      SNAPSHOTS_CASCADE_2[2]["name"],
                      recursively_children=True,
                      recursively_dependents=True,
                      force_umount=True)
        ]
        jdssd.ra.delete_snapshot.assert_has_calls(delete_snapshot_expected)
Пример #8
0
    def test_cascade_volume_delete_snapshots(self):
        jdssd, ctx = self.get_driver(CONFIG_OK)
        o_vname = jcom.vname(UUID_1)

        # Volume with 3 snapshots and no descendants
        # We should delete snapshots and then cal for volume deletion
        o_snaps = SNAPSHOTS_CASCADE_1.copy()

        jdssd.ra.modify_lun.return_value = None
        jdssd.ra.delete_snapshot.return_value = None
        jdssd.ra.get_snapshots.side_effect = [
            SNAPSHOTS_EMPTY, SNAPSHOTS_EMPTY, SNAPSHOTS_EMPTY
        ]

        with mock.patch.object(jdssd, "_gc_delete", return_value=None) as gc:
            jdssd._cascade_volume_delete(o_vname, o_snaps)
            gc.assert_called_once_with(o_vname)
        delete_snapshot_expected = [
            mock.call(o_vname,
                      SNAPSHOTS_CASCADE_1[0]["name"],
                      recursively_children=True,
                      recursively_dependents=True,
                      force_umount=True),
            mock.call(o_vname,
                      SNAPSHOTS_CASCADE_1[1]["name"],
                      recursively_children=True,
                      recursively_dependents=True,
                      force_umount=True),
            mock.call(o_vname,
                      SNAPSHOTS_CASCADE_1[2]["name"],
                      recursively_children=True,
                      recursively_dependents=True,
                      force_umount=True)
        ]
        jdssd.ra.delete_snapshot.assert_has_calls(delete_snapshot_expected)
Пример #9
0
    def test_create_volume_small_block(self):

        jdssd, ctx = self.get_driver(CONFIG_BLOCK_SIZE)
        vol = fake_volume.fake_volume_obj(ctx)
        vol.id = UUID_1
        vol.size = 1
        host = CONFIG_OK["san_hosts"][0]
        port = CONFIG_OK["target_port"]

        target_name = CONFIG_OK["target_prefix"] + UUID_1
        vname = jcom.vname(UUID_1)

        jdssd.ra.create_lun.return_value = None
        jdssd.ra.get_active_host.return_value = host

        ret = jdssd.create_volume(vol)

        jdssd.ra.create_lun.assert_called_once_with(vname,
                                                    o_units.Gi,
                                                    sparse=False,
                                                    block_size="64K")

        location = '{host}:{port},1 {name} 0'.format(host=host,
                                                     port=port,
                                                     name=target_name)
        self.assertEqual(location, ret['provider_location'])
        cred_format = (r"CHAP [0-9,a-z,A-Z]{{{name_len}}} "
                       "[0-9,a-z,A-Z]{{{pass_len}}}").format(
                           name_len=8, pass_len=CONFIG_OK['chap_password_len'])
        self.assertIsNotNone(re.match(cred_format, ret['provider_auth']))
Пример #10
0
    def _create_target_volume(self, volume):
        """Creates target and attach volume to it

        :param volume: volume id
        :return:
        """
        LOG.debug("create target and attach volume %s to it", volume.id)

        target_name = self.jovian_target_prefix + volume.id
        vname = jcom.vname(volume.id)

        auth = volume.provider_auth

        if not auth:
            msg = _("Volume %s is missing provider_auth") % volume.id
            raise exception.VolumeDriverException(msg)

        (__, auth_username, auth_secret) = auth.split()
        chap_cred = {"name": auth_username, "password": auth_secret}

        # Create target
        self._create_target(target_name, True)

        # Attach volume
        self._attach_target_volume(target_name, vname)

        # Set credentials
        self._set_target_credentials(target_name, chap_cred)
Пример #11
0
    def create_volume(self, volume):
        """Create a volume.

        :param volume: volume reference
        :return: model update dict for volume reference
        """
        vname = jcom.vname(volume.id)
        LOG.debug('creating volume %s.', vname)

        provider_location = self._get_provider_location(volume.id)
        provider_auth = self._get_provider_auth()

        try:
            self.ra.create_lun(vname,
                               volume.size * o_units.Gi,
                               sparse=self.jovian_sparse,
                               block_size=self.block_size)

        except jexc.JDSSException as jerr:
            LOG.error("Create volume error. Because %(err)s", {"err": jerr})
            raise exception.VolumeBackendAPIException(
                _('Failed to create volume %s.') % volume.id) from jerr
        ret = {}
        if provider_auth is not None:
            ret['provider_auth'] = provider_auth

        ret['provider_location'] = provider_location

        return ret
Пример #12
0
    def delete_volume(self, volume, cascade=False):
        """Delete volume

        :param volume: volume reference
        :param cascade: remove snapshots of a volume as well
        """
        vname = jcom.vname(volume.id)

        LOG.debug('deleating volume %s', vname)

        snapshots = None
        try:
            snapshots = self.ra.get_snapshots(vname)
        except jexc.JDSSResourceNotFoundException:
            LOG.debug('volume %s dne, it was already ' 'deleted', vname)
            return
        except jexc.JDSSException as jerr:
            raise exception.VolumeBackendAPIException(jerr)

        snapshots = self._clean_garbage_snapshots(vname, snapshots)

        if cascade:
            self._cascade_volume_delete(vname, snapshots)
        else:
            if len(snapshots) > 0:
                self._hide_object(vname)
            else:
                self._gc_delete(vname)
Пример #13
0
    def test_clone_object_exists(self):
        jdssd, ctx = self.get_driver(CONFIG_OK)

        origin = jcom.vname(UUID_1)
        clone = jcom.vname(UUID_2)

        jdssd.ra.create_snapshot.side_effect = (
            jexc.JDSSSnapshotExistsException(snapshot=clone))

        jdssd.ra.delete_snapshot.side_effect = (
            jexc.JDSSSnapshotIsBusyException(snapshot=clone))

        self.assertRaises(exception.Duplicate, jdssd._clone_object, origin,
                          clone)
        jdssd.ra.delete_snapshot.assert_called_once_with(origin, clone)
        jdssd.ra.create_snapshot.assert_called_once_with(origin, clone)
Пример #14
0
    def test_is_target_lun(self):

        jrest, ctx = self.get_rest(CONFIG_OK)
        # lun present
        tname = CONFIG_OK['iscsi_target_prefix'] + UUID_1
        vname = jcom.vname(UUID_1)
        addr = '/san/iscsi/targets/{target}/luns/{lun}'.format(
            target=tname, lun=vname)
        data = {
            "block_size": 512,
            "device_handler": "vdisk_fileio",
            "lun": 0,
            "mode": "wt",
            "name": vname,
            "prod_id": "Storage",
            "scsi_id": "99e2c883331edf87"}
        resp = {'data': data,
                'error': None,
                'code': 200}

        jrest.rproxy.pool_request.return_value = resp
        is_target_lun_expected = [mock.call('GET', addr)]
        self.assertTrue(jrest.is_target_lun(tname, vname))

        url = "http://{ip}:{port}/api/v3/pools/Pool-0{addr}"
        url = url.format(ip=CONFIG_OK['san_hosts'][0],
                         port=CONFIG_OK['san_api_port'],
                         tname=tname,
                         addr=addr)
        msg = "volume name {lun} is not attached to target {target}"
        msg = msg.format(lun=vname, target=tname)
        err = {"class": "opene.exceptions.ItemNotFoundError",
               "message": msg,
               "url": url}

        resp = {'data': None,
                'error': err,
                'code': 404}

        jrest.rproxy.pool_request.return_value = resp
        is_target_lun_expected += [mock.call('GET', addr)]

        self.assertEqual(False, jrest.is_target_lun(tname, vname))

        err = {"class": "some test error",
               "message": "test error message",
               "url": url,
               "errno": 123}

        resp = {'data': None,
                'error': err,
                'code': 500}

        jrest.rproxy.pool_request.return_value = resp
        is_target_lun_expected += [mock.call('GET', addr)]

        self.assertRaises(jexc.JDSSException,
                          jrest.is_target_lun, tname, vname)

        jrest.rproxy.pool_request.assert_has_calls(is_target_lun_expected)
Пример #15
0
    def test_extend_volume(self):
        jdssd, ctx = self.get_driver(CONFIG_OK)
        vol = fake_volume.fake_volume_obj(ctx)
        vol.id = UUID_1
        jdssd.ra.extend_lun.return_value = None
        jdssd.extend_volume(vol, 2)

        jdssd.ra.extend_lun.assert_called_once_with(jcom.vname(UUID_1),
                                                    2147483648)
Пример #16
0
    def test_hide_object(self):
        jdssd, ctx = self.get_driver(CONFIG_OK)
        vname = jcom.vname(UUID_1)

        jdssd.ra.modify_lun.return_value = None
        jdssd._hide_object(vname)

        hidden_volume = {"name": jcom.hidden(UUID_1)}
        jdssd.ra.modify_lun.assert_called_once_with(vname, hidden_volume)
Пример #17
0
    def create_volume_from_snapshot(self, volume, snapshot):
        """Create a volume from a snapshot.

        If volume_type extra specs includes 'replication: <is> True'
        the driver needs to create a volume replica (secondary),
        and setup replication between the newly created volume and
        the secondary volume.
        """
        LOG.debug('create volume %(vol)s from snapshot %(snap)s', {
            'vol': volume.id,
            'snap': snapshot.id
        })

        cvname = jcom.vname(volume.id)
        sname = jcom.sname(snapshot.id)

        self._clone_object(sname, cvname)

        clone_size = 0

        try:
            clone_size = int(self.ra.get_lun(cvname)['volsize'])
        except jexc.JDSSException as jerr:

            self._delete_back_recursively(sname, cvname)
            raise exception.VolumeBackendAPIException(
                _("Fail in cloning snapshot %(snap)s to %(clone)s.") % {
                    'snap': snapshot.id,
                    'clone': volume.id
                }) from jerr

        try:
            if clone_size < o_units.Gi * int(volume.size):
                self.extend_volume(volume, int(volume.size))
        except exception.VolumeBackendAPIException:
            # If volume can't be set to a proper size make sure to clean it
            # before failing
            try:
                self._delete_back_recursively(cvname, cvname)
            except exception.VolumeBackendAPIException as err:
                msg = ("Hidden snapshot %s of volume %s "
                       "have to be removed manualy, "
                       "as automatic removal failed: %s")
                LOG.warning(msg, cvname, sname, err)
            raise

        provider_location = self._get_provider_location(volume.id)
        provider_auth = self._get_provider_auth()

        ret = {}
        if provider_auth is not None:
            ret['provider_auth'] = provider_auth

        ret['provider_location'] = provider_location

        return ret
Пример #18
0
    def test_clone_object_dne(self):
        jdssd, ctx = self.get_driver(CONFIG_OK)
        calls = []
        origin = jcom.vname(UUID_1)
        clone = jcom.vname(UUID_2)
        calls.append(mock.call(origin, clone))

        jdssd.ra.create_snapshot.side_effect = (
            jexc.JDSSResourceNotFoundException(res=origin))

        self.assertRaises(exception.VolumeNotFound, jdssd._clone_object,
                          origin, clone)

        origin = jcom.sname(UUID_1)
        calls.append(mock.call(origin, clone))

        self.assertRaises(exception.SnapshotNotFound, jdssd._clone_object,
                          origin, clone)
        jdssd.ra.create_snapshot.assert_has_calls(calls)
Пример #19
0
    def test_detach_target_vol(self):

        jrest, ctx = self.get_rest(CONFIG_OK)
        # detach target vol ok
        tname = CONFIG_OK['iscsi_target_prefix'] + UUID_1
        vname = jcom.vname(UUID_1)

        addr = '/san/iscsi/targets/{tar}/luns/{vol}'.format(
            tar=tname, vol=vname)

        resp = {'data': None,
                'error': None,
                'code': 204}

        jrest.rproxy.pool_request.return_value = resp
        detach_target_vol_expected = [
            mock.call('DELETE', addr)]
        self.assertIsNone(jrest.detach_target_vol(tname, vname))

        # no such target
        url = 'http://85.14.118.246:11582/api/v3/pools/Pool-0/{}'.format(addr)
        msg = 'Target {} not exists.'.format(vname)
        err = {"class": "opene.exceptions.ItemNotFoundError",
               "message": msg,
               "url": url}

        resp = {'data': None,
                'error': err,
                'code': 404}

        jrest.rproxy.pool_request.return_value = resp
        detach_target_vol_expected += [
            mock.call('DELETE', addr)]
        self.assertRaises(jexc.JDSSResourceNotFoundException,
                          jrest.detach_target_vol, tname, vname)

        # error unknown
        url = 'http://85.14.118.246:11582/api/v3/pools/Pool-0/{}'.format(addr)
        msg = 'Target {} not exists.'.format(vname)

        err = {"class": "some test error",
               "message": "test error message",
               "url": url,
               "errno": 125}

        resp = {'data': None,
                'error': err,
                'code': 500}

        jrest.rproxy.pool_request.return_value = resp
        detach_target_vol_expected += [
            mock.call('DELETE', addr)]
        self.assertRaises(jexc.JDSSException,
                          jrest.detach_target_vol, tname, vname)
        jrest.rproxy.pool_request.assert_has_calls(detach_target_vol_expected)
Пример #20
0
    def test_delete_back_recursively_single_snapshot(self):

        jdssd, ctx = self.get_driver(CONFIG_OK)
        opvname = jcom.hidden(UUID_2)
        opsname = jcom.sname(UUID_3)

        jdssd.ra.get_snapshots.side_effect = [
            SNAPSHOTS_RECURSIVE_CHAIN_1.copy(),
            SNAPSHOTS_RECURSIVE_CHAIN_2.copy()
        ]

        origin = "Pool-0/{vorig}@{sorig}".format(vorig=jcom.vname(UUID_1),
                                                 sorig=jcom.vname(UUID_2))
        get_lun_resp = {
            'origin': origin,
            'vscan': None,
            'full_name': 'Pool-0/' + jcom.hidden(UUID_2),
            'userrefs': None,
            'primarycache': 'all',
            'logbias': 'latency',
            'creation': '1591543140',
            'sync': 'always',
            'is_clone': True,
            'dedup': 'off',
            'sharenfs': None,
            'receive_resume_token': None,
            'volsize': '1073741824'
        }
        jdssd.ra.get_lun.return_value = get_lun_resp
        jdssd._delete_back_recursively(opvname, opsname)

        jdssd.ra.delete_snapshot.assert_called_once_with(
            jcom.vname(UUID_1),
            jcom.vname(UUID_2),
            recursively_children=True,
            recursively_dependents=True,
            force_umount=True)

        get_snapshots_expected = [mock.call(opvname)]
        jdssd.ra.get_snapshots.assert_has_calls(get_snapshots_expected)
Пример #21
0
    def extend_volume(self, volume, new_size):
        """Extend an existing volume.

        :param volume: volume reference
        :param new_size: volume new size in GB
        """
        LOG.debug("Extend volume %s", volume.id)

        try:
            self.ra.extend_lun(jcom.vname(volume.id), new_size * o_units.Gi)
        except jexc.JDSSException as jerr:
            raise exception.VolumeBackendAPIException(
                (_('Failed to extend volume %s.'), volume.id)) from jerr
Пример #22
0
    def test_is_lun(self):

        jrest, ctx = self.get_rest(CONFIG_OK)
        resp = {'data': {
                "vscan": None,
                "full_name": "pool-0/" + jcom.vname(UUID_1),
                "userrefs": None,
                "primarycache": "all",
                "logbias": "latency",
                "creation": "1591543140",
                "sync": "always",
                "is_clone": False,
                "dedup": "off",
                "sharenfs": None,
                "receive_resume_token": None,
                "volsize": "1073741824"},
                'error': None,
                'code': 200}

        jrest.rproxy.pool_request.return_value = resp
        self.assertTrue(jrest.is_lun(jcom.vname(UUID_1)))

        err = {'errno': 1,
               'message': ('Zfs resource: Pool-0/' + jcom.vname(UUID_1) +
                           ' not found in this collection.')}
        resp = {'code': 500,
                'data': None,
                'error': err}

        jrest.rproxy.pool_request.return_value = resp
        self.assertEqual(False, jrest.is_lun(jcom.vname(UUID_1)))

        jrest.rproxy.pool_request.side_effect = (
            jexc.JDSSRESTProxyException(host='test_host', reason='test'))

        self.assertRaises(jexc.JDSSRESTProxyException,
                          jrest.is_lun,
                          'v_' + UUID_1)
Пример #23
0
    def test_delete_back_recursively_res_active(self):

        jdssd, ctx = self.get_driver(CONFIG_OK)
        opvname = jcom.vname(UUID_1)
        opsname = jcom.sname(UUID_2)

        jdssd._delete_back_recursively(opvname, opsname)

        jdssd.ra.delete_snapshot.assert_called_once_with(
            opvname,
            opsname,
            recursively_children=True,
            recursively_dependents=True,
            force_umount=True)
Пример #24
0
    def _remove_target_volume(self, volume):
        """_remove_target_volume

        Ensure that volume is not attached to target and target do not exists.
        """
        target_name = self.jovian_target_prefix + volume.id
        LOG.debug("remove export")
        LOG.debug("detach volume:%(vol)s from target:%(targ)s.", {
            'vol': volume,
            'targ': target_name
        })

        try:
            self.ra.detach_target_vol(target_name, jcom.vname(volume.id))
        except jexc.JDSSResourceNotFoundException as jerrrnf:
            LOG.debug('failed to remove resource %(t)s because of %(err)s', {
                't': target_name,
                'err': jerrrnf.args[0]
            })
        except jexc.JDSSException as jerr:
            LOG.debug(
                'failed to Terminate_connection for target %(targ)s '
                'because of: %(err)s', {
                    'targ': target_name,
                    'err': jerr.args[0]
                })
            raise exception.VolumeBackendAPIException(jerr)

        LOG.debug("delete target: %s", target_name)

        try:
            self.ra.delete_target(target_name)
        except jexc.JDSSResourceNotFoundException as jerrrnf:
            LOG.debug(
                'failed to remove resource %(target)s because '
                'of %(err)s', {
                    'target': target_name,
                    'err': jerrrnf.args[0]
                })

        except jexc.JDSSException as jerr:
            LOG.debug(
                'Failed to Terminate_connection for target %(targ)s '
                'because of: %(err)s ', {
                    'targ': target_name,
                    'err': jerr.args[0]
                })

            raise exception.VolumeBackendAPIException(jerr)
Пример #25
0
    def test_remove_target_volume(self):

        jdssd, ctx = self.get_driver(CONFIG_OK)

        vol = fake_volume.fake_volume_obj(ctx)
        vol.id = UUID_1
        target_name = CONFIG_OK['target_prefix'] + UUID_1

        jdssd.ra.detach_target_vol.return_value = None
        jdssd.ra.delete_target.return_value = None

        jdssd._remove_target_volume(vol)

        jdssd.ra.detach_target_vol.assert_called_once_with(
            target_name, jcom.vname(UUID_1))
        jdssd.ra.delete_target.assert_called_with(target_name)
Пример #26
0
    def test_clean_garbage_snapshots(self):
        jdssd, ctx = self.get_driver(CONFIG_OK)
        o_vname = jcom.vname(UUID_1)
        o_snaps = SNAPSHOTS_GARBAGE.copy()

        jdssd.ra.delete_snapshot.return_value = None
        jdssd._clean_garbage_snapshots(o_vname, o_snaps)
        jdssd.ra.delete_snapshot.assert_called_once_with(
            o_vname, SNAPSHOTS_GARBAGE[1]["name"])
        # Test exception handling
        for exc in get_jdss_exceptions():
            o_snaps = SNAPSHOTS_GARBAGE.copy()
            jdssd.ra.delete_snapshot.side_effect = exc
            try:
                jdssd._clean_garbage_snapshots(o_vname, o_snaps)
            except Exception as err:
                self.assertIsInstance(err, exception.VolumeBackendAPIException)
Пример #27
0
    def test_remove_target_volume_fail_to_delete(self):

        jdssd, ctx = self.get_driver(CONFIG_OK)

        vol = fake_volume.fake_volume_obj(ctx)
        vol.id = UUID_1
        target_name = CONFIG_OK['target_prefix'] + UUID_1

        jdssd.ra.detach_target_vol.return_value = None
        jdssd.ra.delete_target.side_effect = (jexc.JDSSRESTException(
            reason='running test', request='test'))

        self.assertRaises(exception.VolumeBackendAPIException,
                          jdssd._remove_target_volume, vol)

        jdssd.ra.detach_target_vol.assert_called_once_with(
            target_name, jcom.vname(UUID_1))
        jdssd.ra.delete_target.assert_called_with(target_name)
Пример #28
0
    def test_remove_target_volume_no_target(self):

        jdssd, ctx = self.get_driver(CONFIG_OK)

        vol = fake_volume.fake_volume_obj(ctx)
        vol.id = UUID_1
        target_name = CONFIG_OK['target_prefix'] + UUID_1

        jdssd.ra.detach_target_vol.return_value = None
        jdssd.ra.detach_target_vol.side_effect = (
            jexc.JDSSResourceNotFoundException(res=target_name))
        jdssd.ra.delete_target.return_value = None

        jdssd._remove_target_volume(vol)

        jdssd.ra.detach_target_vol.assert_called_once_with(
            target_name, jcom.vname(UUID_1))
        jdssd.ra.delete_target.assert_called_with(target_name)
Пример #29
0
    def _ensure_target_volume(self, volume):
        """Checks if target configured properly and volume is attached to it

        param: volume: volume structure
        """
        LOG.debug("ensure volume %s assigned to a proper target", volume.id)

        target_name = self.jovian_target_prefix + volume.id

        auth = volume.provider_auth

        if not auth:
            msg = _("volume {} is missing provider_auth").format(volume.id)
            raise exception.VolumeDriverException(msg)

        (__, auth_username, auth_secret) = auth.split()
        chap_cred = {"name": auth_username,
                     "password": auth_secret}

        if not self.ra.is_target(target_name):
            self._create_target_volume(volume)
            return

        if not self.ra.is_target_lun(target_name, volume.id):
            vname = jcom.vname(volume.id)
            self._attach_target_volume(target_name, vname)

        try:
            users = self.ra.get_target_user(target_name)
            if len(users) == 1:
                if users[0]['name'] == chap_cred['name']:
                    return
                self.ra.delete_target_user(
                    target_name,
                    users[0]['name'])
            for user in users:
                self.ra.delete_target_user(
                    target_name,
                    user['name'])
            self._set_target_credentials(target_name, chap_cred)

        except jexc.JDSSException as err:
            self.ra.delete_target(target_name)
            raise exception.VolumeBackendAPIException(err)
Пример #30
0
    def test_create_snapshot(self):
        jdssd, ctx = self.get_driver(CONFIG_OK)

        vname = jcom.vname(UUID_1)

        sname = jcom.sname(UUID_2)

        snap = fake_snapshot.fake_snapshot_obj(ctx, id=UUID_2)
        snap.volume_id = UUID_1

        patches = [
            mock.patch.object(jdssd, "_clone_object", return_value=None)
        ]

        self.start_patches(patches)

        jdssd.create_snapshot(snap)

        jdssd._clone_object.assert_called_once_with(vname, sname)
        self.stop_patches(patches)