Exemplo n.º 1
0
    def _get_access_entries_according_to_mapping(self, access_mapping):

        access_list = []

        for access_type, protocols in access_mapping.items():
            if access_type.lower() == 'cert':
                access_to = CONF.data_node_access_cert
            elif access_type.lower() == 'ip':
                access_to = CONF.data_node_access_ip
            elif access_type.lower() == 'user':
                access_to = CONF.data_node_access_admin_user
            else:
                msg = _("Unsupported access type provided: %s.") % access_type
                raise exception.ShareDataCopyFailed(reason=msg)
            if not access_to:
                msg = _("Configuration for Data node mounting access type %s "
                        "has not been set.") % access_type
                raise exception.ShareDataCopyFailed(reason=msg)

            access = {
                'access_type': access_type,
                'access_level': constants.ACCESS_LEVEL_RW,
                'access_to': access_to,
            }
            access_list.append(access)

        return access_list
Exemplo n.º 2
0
def _validate_item(src_item, dest_item):
    src_sum, err = utils.execute(
        "sha256sum", "%s" % src_item, run_as_root=True)
    dest_sum, err = utils.execute(
        "sha256sum", "%s" % dest_item, run_as_root=True)
    if src_sum.split()[0] != dest_sum.split()[0]:
        msg = _("Data corrupted while copying. Aborting data copy.")
        raise exception.ShareDataCopyFailed(reason=msg)
Exemplo n.º 3
0
    def test_copy_data(self):

        values = [("folder1/\nitem/\nfile1\nitem", ""), "", ("", ""),
                  ("10000", ""), "", ""]

        def get_output(*args, **kwargs):
            return values.pop(0)

        # mocks
        self.mock_object(
            data_utils, '_validate_item',
            mock.Mock(side_effect=[
                exception.ShareDataCopyFailed(reason='fake'), None
            ]))
        self.mock_object(utils, 'execute', mock.Mock(side_effect=get_output))
        self.mock_object(self._copy, 'get_progress')

        # run
        self._copy.copy_data(self._copy.src)

        # asserts
        self._copy.get_progress.assert_called_once_with()

        utils.execute.assert_has_calls([
            mock.call("ls",
                      "-pA1",
                      "--group-directories-first",
                      self._copy.src,
                      run_as_root=True),
            mock.call("mkdir",
                      "-p",
                      os.path.join(self._copy.dest, "folder1/"),
                      run_as_root=True),
            mock.call("ls",
                      "-pA1",
                      "--group-directories-first",
                      os.path.join(self._copy.src, "folder1/"),
                      run_as_root=True),
            mock.call("stat",
                      "-c",
                      "%s",
                      os.path.join(self._copy.src, "file1"),
                      run_as_root=True),
            mock.call("cp",
                      "-P",
                      "--preserve=all",
                      os.path.join(self._copy.src, "file1"),
                      os.path.join(self._copy.dest, "file1"),
                      run_as_root=True),
            mock.call("cp",
                      "-P",
                      "--preserve=all",
                      os.path.join(self._copy.src, "file1"),
                      os.path.join(self._copy.dest, "file1"),
                      run_as_root=True)
        ])
Exemplo n.º 4
0
    def migration_start(self, context, ignore_list, share_id,
                        share_instance_id, dest_share_instance_id,
                        connection_info_src, connection_info_dest):

        LOG.debug(
            "Received request to migrate share content from share instance "
            "%(instance_id)s to instance %(dest_instance_id)s.", {
                'instance_id': share_instance_id,
                'dest_instance_id': dest_share_instance_id
            })

        share_ref = self.db.share_get(context, share_id)
        share_instance_ref = self.db.share_instance_get(context,
                                                        share_instance_id,
                                                        with_share_data=True)

        share_rpcapi = share_rpc.ShareAPI()

        mount_path = CONF.mount_tmp_location

        try:
            copy = data_utils.Copy(
                os.path.join(mount_path, share_instance_id),
                os.path.join(mount_path, dest_share_instance_id), ignore_list,
                CONF.check_hash)

            self._copy_share_data(context, copy, share_ref, share_instance_id,
                                  dest_share_instance_id, connection_info_src,
                                  connection_info_dest)
        except exception.ShareDataCopyCancelled:
            share_rpcapi.migration_complete(context, share_instance_ref,
                                            dest_share_instance_id)
            return
        except Exception:
            self.db.share_update(
                context, share_id,
                {'task_state': constants.TASK_STATE_DATA_COPYING_ERROR})
            msg = _("Failed to copy contents from instance %(src)s to "
                    "instance %(dest)s.") % {
                        'src': share_instance_id,
                        'dest': dest_share_instance_id
                    }
            LOG.exception(msg)
            share_rpcapi.migration_complete(context, share_instance_ref,
                                            dest_share_instance_id)
            raise exception.ShareDataCopyFailed(reason=msg)
        finally:
            self.busy_tasks_shares.pop(share_id, None)

        LOG.info(
            "Completed copy operation of migrating share content from share "
            "instance %(instance_id)s to instance %(dest_instance_id)s.", {
                'instance_id': share_instance_id,
                'dest_instance_id': dest_share_instance_id
            })
Exemplo n.º 5
0
    def allow_access_to_data_service(self, share, share_instance_id,
                                     dest_share_instance_id):

        if share['share_proto'].upper() == 'GLUSTERFS':

            access_to = CONF.data_node_access_cert
            access_type = 'cert'

            if not access_to:
                msg = _("Data Node Certificate not specified. Cannot mount "
                        "instances for data copy of share %(share_id)s. "
                        "Aborting.") % {
                            'share_id': share['id']
                        }
                raise exception.ShareDataCopyFailed(reason=msg)

        else:

            access_to = CONF.data_node_access_ip
            access_type = 'ip'

            if not access_to:
                msg = _("Data Node Admin Network IP not specified. Cannot "
                        "mount instances for data copy of share %(share_id)s. "
                        "Aborting.") % {
                            'share_id': share['id']
                        }
                raise exception.ShareDataCopyFailed(reason=msg)

        access = {
            'access_type': access_type,
            'access_level': constants.ACCESS_LEVEL_RW,
            'access_to': access_to
        }

        access_ref = self._allow_data_access(access, share_instance_id,
                                             dest_share_instance_id)

        return access_ref
Exemplo n.º 6
0
    def _get_access_entries_according_to_mapping(self, access_mapping):

        access_list = []

        # NOTE(ganso): protocol is not relevant here because we previously
        # used it to filter the access types we are interested in
        for access_type, protocols in access_mapping.items():
            access_to_list = []
            if access_type.lower() == 'cert' and CONF.data_node_access_cert:
                access_to_list.append(CONF.data_node_access_cert)
            elif access_type.lower() == 'ip':
                ips = CONF.data_node_access_ips
                if ips:
                    if not isinstance(ips, list):
                        ips = [ips]
                    access_to_list.extend(ips)
            elif (access_type.lower() == 'user'
                  and CONF.data_node_access_admin_user):
                access_to_list.append(CONF.data_node_access_admin_user)
            else:
                msg = _("Unsupported access type provided: %s.") % access_type
                raise exception.ShareDataCopyFailed(reason=msg)
            if not access_to_list:
                msg = _("Configuration for Data node mounting access type %s "
                        "has not been set.") % access_type
                raise exception.ShareDataCopyFailed(reason=msg)

            for access_to in access_to_list:
                access = {
                    'access_type': access_type,
                    'access_level': constants.ACCESS_LEVEL_RW,
                    'access_to': access_to,
                }
                access_list.append(access)

        return access_list
Exemplo n.º 7
0
    def test__copy_share_data_exception_access(self):

        connection_info_src = {
            'mount': 'mount_cmd_src',
            'unmount': 'unmount_cmd_src'
        }
        connection_info_dest = {
            'mount': 'mount_cmd_src',
            'unmount': 'unmount_cmd_src'
        }

        fake_copy = mock.MagicMock(cancelled=False)

        # mocks
        self.mock_object(db, 'share_update')
        self.mock_object(
            db, 'share_instance_get',
            mock.Mock(
                side_effect=[self.share['instance'], self.share['instance']]))

        self.mock_object(
            helper.DataServiceHelper, 'allow_access_to_data_service',
            mock.Mock(side_effect=exception.ShareDataCopyFailed(
                reason='fake')))

        self.mock_object(helper.DataServiceHelper, 'cleanup_data_access')

        # run
        self.assertRaises(exception.ShareDataCopyFailed,
                          self.manager._copy_share_data, self.context,
                          fake_copy, self.share, 'ins1_id', 'ins2_id',
                          connection_info_src, connection_info_dest)

        # asserts
        db.share_update.assert_called_once_with(
            self.context, self.share['id'],
            {'task_state': constants.TASK_STATE_DATA_COPYING_STARTING})

        (helper.DataServiceHelper.allow_access_to_data_service.
         assert_called_once_with(self.share['instance'], connection_info_src,
                                 self.share['instance'], connection_info_dest))
Exemplo n.º 8
0
    def _copy_share_data(self, context, copy, src_share, share_instance_id,
                         dest_share_instance_id, connection_info_src,
                         connection_info_dest):

        copied = False
        mount_path = CONF.mount_tmp_location

        share_instance = self.db.share_instance_get(context,
                                                    share_instance_id,
                                                    with_share_data=True)
        dest_share_instance = self.db.share_instance_get(
            context, dest_share_instance_id, with_share_data=True)

        self.db.share_update(
            context, src_share['id'],
            {'task_state': constants.TASK_STATE_DATA_COPYING_STARTING})

        helper_src = helper.DataServiceHelper(context, self.db, src_share)
        helper_dest = helper_src

        access_ref_list_src = helper_src.allow_access_to_data_service(
            share_instance, connection_info_src, dest_share_instance,
            connection_info_dest)
        access_ref_list_dest = access_ref_list_src

        def _call_cleanups(items):
            for item in items:
                if 'unmount_src' == item:
                    helper_src.cleanup_unmount_temp_folder(
                        connection_info_src['unmount'], mount_path,
                        share_instance_id)
                elif 'temp_folder_src' == item:
                    helper_src.cleanup_temp_folder(share_instance_id,
                                                   mount_path)
                elif 'temp_folder_dest' == item:
                    helper_dest.cleanup_temp_folder(dest_share_instance_id,
                                                    mount_path)
                elif 'access_src' == item:
                    helper_src.cleanup_data_access(access_ref_list_src,
                                                   share_instance_id)
                elif 'access_dest' == item:
                    helper_dest.cleanup_data_access(access_ref_list_dest,
                                                    dest_share_instance_id)

        try:
            helper_src.mount_share_instance(connection_info_src['mount'],
                                            mount_path, share_instance)
        except Exception:
            msg = _("Data copy failed attempting to mount "
                    "share instance %s.") % share_instance_id
            LOG.exception(msg)
            _call_cleanups(['temp_folder_src', 'access_dest', 'access_src'])
            raise exception.ShareDataCopyFailed(reason=msg)

        try:
            helper_dest.mount_share_instance(connection_info_dest['mount'],
                                             mount_path, dest_share_instance)
        except Exception:
            msg = _("Data copy failed attempting to mount "
                    "share instance %s.") % dest_share_instance_id
            LOG.exception(msg)
            _call_cleanups([
                'temp_folder_dest', 'unmount_src', 'temp_folder_src',
                'access_dest', 'access_src'
            ])
            raise exception.ShareDataCopyFailed(reason=msg)

        self.busy_tasks_shares[src_share['id']] = copy
        self.db.share_update(
            context, src_share['id'],
            {'task_state': constants.TASK_STATE_DATA_COPYING_IN_PROGRESS})

        try:
            copy.run()

            self.db.share_update(
                context, src_share['id'],
                {'task_state': constants.TASK_STATE_DATA_COPYING_COMPLETING})

            if copy.get_progress()['total_progress'] == 100:
                copied = True

        except Exception:
            LOG.exception(
                "Failed to copy data from share instance "
                "%(share_instance_id)s to "
                "%(dest_share_instance_id)s.", {
                    'share_instance_id': share_instance_id,
                    'dest_share_instance_id': dest_share_instance_id
                })

        try:
            helper_src.unmount_share_instance(connection_info_src['unmount'],
                                              mount_path, share_instance_id)
        except Exception:
            LOG.exception(
                "Could not unmount folder of instance"
                " %s after its data copy.", share_instance_id)

        try:
            helper_dest.unmount_share_instance(connection_info_dest['unmount'],
                                               mount_path,
                                               dest_share_instance_id)
        except Exception:
            LOG.exception(
                "Could not unmount folder of instance"
                " %s after its data copy.", dest_share_instance_id)

        try:
            helper_src.deny_access_to_data_service(access_ref_list_src,
                                                   share_instance)
        except Exception:
            LOG.exception(
                "Could not deny access to instance"
                " %s after its data copy.", share_instance_id)

        try:
            helper_dest.deny_access_to_data_service(access_ref_list_dest,
                                                    dest_share_instance)
        except Exception:
            LOG.exception(
                "Could not deny access to instance"
                " %s after its data copy.", dest_share_instance_id)

        if copy and copy.cancelled:
            self.db.share_update(
                context, src_share['id'],
                {'task_state': constants.TASK_STATE_DATA_COPYING_CANCELLED})
            LOG.warning(
                "Copy of data from share instance "
                "%(src_instance)s to share instance "
                "%(dest_instance)s was cancelled.", {
                    'src_instance': share_instance_id,
                    'dest_instance': dest_share_instance_id
                })
            raise exception.ShareDataCopyCancelled(
                src_instance=share_instance_id,
                dest_instance=dest_share_instance_id)

        elif not copied:
            msg = _("Copying data from share instance %(instance_id)s "
                    "to %(dest_instance_id)s did not succeed.") % (
                        {
                            'instance_id': share_instance_id,
                            'dest_instance_id': dest_share_instance_id
                        })
            raise exception.ShareDataCopyFailed(reason=msg)

        self.db.share_update(
            context, src_share['id'],
            {'task_state': constants.TASK_STATE_DATA_COPYING_COMPLETED})

        LOG.debug(
            "Copy of data from share instance %(src_instance)s to "
            "share instance %(dest_instance)s was successful.", {
                'src_instance': share_instance_id,
                'dest_instance': dest_share_instance_id
            })