Exemple #1
0
    def update_nfs_access_rule(self,
                               host_list,
                               share_id=None,
                               snapshot_id=None):
        if share_id is not None:
            name = os.path.join('/shares', share_id)
        elif snapshot_id is not None:
            name = os.path.join('/snapshots', snapshot_id)
        else:
            msg = _("No share/snapshot provided to update NFS rules.")
            raise exception.HNASBackendException(msg=msg)

        command = ['nfs-export', 'mod', '-c']

        if len(host_list) == 0:
            command.append('127.0.0.1')
        else:
            string_command = '"' + six.text_type(host_list[0])

            for i in range(1, len(host_list)):
                string_command += ',' + (six.text_type(host_list[i]))
            string_command += '"'
            command.append(string_command)

        command.append(name)
        try:
            self._execute(command)
        except processutils.ProcessExecutionError:
            msg = _("Could not update access rules for NFS export %s.") % name
            LOG.exception(msg)
            raise exception.HNASBackendException(msg=msg)
Exemple #2
0
    def _locked_selectfs(self, op, path):
        if op == 'create':
            command = [
                'selectfs', self.fs_name, '\n', 'ssc', '127.0.0.1',
                'console-context', '--evs', self.evs_id, 'mkdir', '-p', path
            ]
            try:
                self._execute(command)
            except processutils.ProcessExecutionError:
                msg = _("Failed to create directory %s.") % path
                LOG.exception(msg)
                raise exception.HNASBackendException(msg=msg)

        if op == 'delete':
            command = [
                'selectfs', self.fs_name, '\n', 'ssc', '127.0.0.1',
                'console-context', '--evs', self.evs_id, 'rmdir', path
            ]
            try:
                self._execute(command)
            except processutils.ProcessExecutionError as e:
                if 'DirectoryNotEmpty' in e.stderr:
                    LOG.debug("Share %(path)s has more snapshots.",
                              {'path': path})
                elif 'NotFound' in e.stderr:
                    LOG.warning(
                        _LW("Attempted to delete path %s but it does "
                            "not exist."), path)
                else:
                    msg = _("Failed to delete directory %s.") % path
                    LOG.exception(msg)
                    raise exception.HNASBackendException(msg=msg)
Exemple #3
0
    def test_create_share_from_snapshot_cleanup(self):
        dest_path = '/snapshots/' + share_nfs['id'] + '/' + snapshot_nfs['id']
        src_path = '/shares/' + share_nfs['id']

        self.mock_object(driver.HitachiHNASDriver, "_check_fs_mounted",
                         mock.Mock())
        self.mock_object(ssh.HNASSSHBackend, "vvol_create")
        self.mock_object(ssh.HNASSSHBackend, "quota_add")
        self.mock_object(ssh.HNASSSHBackend, "tree_clone")
        self.mock_object(ssh.HNASSSHBackend, "vvol_delete")
        self.mock_object(
            ssh.HNASSSHBackend, "nfs_export_add",
            mock.Mock(side_effect=exception.HNASBackendException(
                msg='Error adding nfs export.')))

        self.assertRaises(exception.HNASBackendException,
                          self._driver.create_share_from_snapshot, 'context',
                          share_nfs, snapshot_nfs)

        ssh.HNASSSHBackend.vvol_create.assert_called_once_with(share_nfs['id'])
        ssh.HNASSSHBackend.quota_add.assert_called_once_with(
            share_nfs['id'], share_nfs['size'])
        ssh.HNASSSHBackend.tree_clone.assert_called_once_with(
            dest_path, src_path)
        ssh.HNASSSHBackend.nfs_export_add.assert_called_once_with(
            share_nfs['id'])
        ssh.HNASSSHBackend.vvol_delete.assert_called_once_with(share_nfs['id'])
Exemple #4
0
    def cifs_allow_access(self, name, user, permission, is_snapshot=False):
        command = [
            'cifs-saa', 'add', '--target-label', self.fs_name, name, user,
            permission
        ]

        try:
            self._execute(command)
        except processutils.ProcessExecutionError as e:
            if 'already listed as a user' in e.stderr:
                if is_snapshot:
                    LOG.debug(
                        'User %(user)s already allowed to access '
                        'snapshot %(snapshot)s.', {
                            'user': user,
                            'snapshot': name,
                        })
                else:
                    self._update_cifs_rule(name, user, permission)
            else:
                entity_type = "share"
                if is_snapshot:
                    entity_type = "snapshot"

                msg = _("Could not add access of user %(user)s to "
                        "%(entity_type)s %(name)s.") % {
                            'user': user,
                            'name': name,
                            'entity_type': entity_type,
                        }
                LOG.exception(msg)
                raise exception.HNASBackendException(msg=msg)
Exemple #5
0
    def _deny_access(self, share_id, host, permission):
        """Deny access to the share.

        :param share_id: ID of share that access will be denied.
        :param host: Host to which access will be denied.
        :param permission: permission (e.g. 'rw', 'ro') that will be denied.
        """
        # check if the share exists
        self._ensure_share(share_id)

        # get the list that contains all the hosts allowed on the share
        host_list = self.hnas.get_host_list(share_id)

        if permission in ('ro', 'rw'):
            host_access = host + '(' + permission + ')'
        else:
            msg = (_("Permission should be 'ro' or 'rw' instead "
                     "of %s") % permission)
            raise exception.HNASBackendException(msg=msg)

        # check if the host(s) is already not allowed
        if host_access not in host_list:
            LOG.debug("Host: %(host)s is already not allowed.", {'host': host})
        else:
            # remove the host on host_list
            host_list.remove(host_access)
            self.hnas.update_access_rule(share_id, host_list)
Exemple #6
0
    def _allow_access(self, share_id, host, permission='rw'):
        """Allow access to the share.

        :param share_id: ID of share that access will be allowed.
        :param host: Host to which access will be allowed.
        :param permission: permission (e.g. 'rw', 'ro') that will be allowed.
        """
        # check if the share exists
        self._ensure_share(share_id)

        # get the list that contains all the hosts allowed on the share
        host_list = self.hnas.get_host_list(share_id)

        if permission in ('ro', 'rw'):
            host_access = host + '(' + permission + ')'
        else:
            msg = (_("Permission should be 'ro' or 'rw' instead "
                     "of %s") % permission)
            raise exception.HNASBackendException(msg=msg)

        # check if the host(s) is already allowed
        if any(host in x for x in host_list):
            if host_access in host_list:
                LOG.debug("Host: %(host)s is already allowed.", {'host': host})
            else:
                # remove all the hosts with different permissions
                host_list = [x for x in host_list if not x.startswith(host)]
                # add the host with new permission
                host_list.append(host_access)
                self.hnas.update_access_rule(share_id, host_list)
        else:
            host_list.append(host_access)
            self.hnas.update_access_rule(share_id, host_list)
Exemple #7
0
    def cifs_deny_access(self, name, user, is_snapshot=False):
        command = [
            'cifs-saa', 'delete', '--target-label', self.fs_name, name, user
        ]

        entity_type = "share"
        if is_snapshot:
            entity_type = "snapshot"

        try:
            self._execute(command)
        except processutils.ProcessExecutionError as e:
            if ('not listed as a user' in e.stderr
                    or 'Could not delete user/group' in e.stderr):
                LOG.warning(
                    'User %(user)s already not allowed to access '
                    '%(entity_type)s %(name)s.', {
                        'entity_type': entity_type,
                        'user': user,
                        'name': name
                    })
            else:
                msg = _("Could not delete access of user %(user)s to "
                        "%(entity_type)s %(name)s.") % {
                            'user': user,
                            'name': name,
                            'entity_type': entity_type,
                        }
                LOG.exception(msg)
                raise exception.HNASBackendException(msg=msg)
Exemple #8
0
    def deny_access(self, share_id, host, share_proto, permission):
        """Deny access to the share.

        :param share_id: ID of share that access will be denied.
        :param host: Host to which access will be denied.
        :param share_proto: Storage protocol of share. Currently,
        only NFS storage protocol is supported.
        :param permission: permission (e.g. 'rw', 'ro') that will be denied.
        """
        # check if the share exists
        self.ensure_share(share_id, share_proto)
        export = self._nfs_export_list(share_id)

        # get the list that contains all the hosts allowed on the share
        host_list = export[0].export_configuration

        if permission in ('ro', 'rw'):
            host_access = host + '(' + permission + ')'
        else:
            msg = (_("Permission should be 'ro' or 'rw' instead "
                     "of %s") % permission)
            raise exception.HNASBackendException(msg=msg)

        # check if the host(s) is already not allowed
        if host_access not in host_list:
            LOG.debug("Host: %(host)s is already not allowed.", {'host': host})
        else:
            # remove the host on host_list
            host_list.remove(host_access)
            self._update_access_rule(share_id, host_list)
Exemple #9
0
    def _get_export(self, name, is_snapshot=False):
        if is_snapshot:
            name = '/snapshots/' + name
        else:
            name = '/shares/' + name

        command = ['nfs-export', 'list ', name]
        export_list = []
        try:
            output, err = self._execute(command)
        except processutils.ProcessExecutionError as e:
            if 'does not exist' in e.stderr:
                msg = _("Export %(name)s was not found in EVS "
                        "%(evs_id)s.") % {
                            'name': name,
                            'evs_id': self.evs_id,
                        }
                LOG.exception(msg)
                raise exception.HNASItemNotFoundException(msg=msg)
            else:
                msg = _("Could not list NFS exports by name %s.") % name
                LOG.exception(msg)
                raise exception.HNASBackendException(msg=msg)
        items = output.split('Export name')

        if items[0][0] == '\n':
            items.pop(0)

        for i in range(0, len(items)):
            export_list.append(Export(items[i]))
        return export_list
Exemple #10
0
 def _check_export(self, vvol_name):
     export = self._nfs_export_list(vvol_name)
     if (vvol_name in export[0].export_name
             and self.fs_name in export[0].file_system_label):
         return True
     else:
         msg = (_("Export %s does not exist.") % export[0].export_name)
         raise exception.HNASBackendException(msg=msg)
Exemple #11
0
    def _check_quota(self, vvol_name):
        command = ['quota', 'list', '--verbose', self.fs_name, vvol_name]
        output, err = self._execute(command)

        if 'No quotas matching specified filter criteria' not in output:
            return True
        else:
            msg = (_("Virtual volume %s does not have any quota.") % vvol_name)
            raise exception.HNASBackendException(msg=msg)
Exemple #12
0
 def mount(self):
     command = ['mount', self.fs_name]
     try:
         self._execute(command)
     except processutils.ProcessExecutionError as e:
         if 'file system is already mounted' not in e.stderr:
             msg = _("Failed to mount filesystem %s.") % self.fs_name
             LOG.exception(msg)
             raise exception.HNASBackendException(msg=msg)
Exemple #13
0
    def _locked_selectfs(self, op, path):
        if op == 'create':
            command = [
                'selectfs', self.fs_name, '\n', 'ssc', '127.0.0.1',
                'console-context', '--evs', self.evs_id, 'mkdir', '-p', path
            ]
            try:
                self._execute(command)
            except processutils.ProcessExecutionError as e:
                if "Current file system invalid: VolumeNotFound" in e.stderr:
                    msg = _("Command to create directory %s failed due to "
                            "context change.") % path
                    LOG.debug(msg)
                    raise exception.HNASSSCContextChange(msg=msg)
                else:
                    msg = _("Failed to create directory %s.") % path
                    LOG.exception(msg)
                    raise exception.HNASBackendException(msg=msg)

        if op == 'delete':
            command = [
                'selectfs', self.fs_name, '\n', 'ssc', '127.0.0.1',
                'console-context', '--evs', self.evs_id, 'rmdir', path
            ]
            try:
                self._execute(command)
            except processutils.ProcessExecutionError as e:
                if 'DirectoryNotEmpty' in e.stderr:
                    msg = _("Share %s has more snapshots.") % path
                    LOG.debug(msg)
                    raise exception.HNASDirectoryNotEmpty(msg=msg)
                elif 'cannot remove' in e.stderr and 'NotFound' in e.stderr:
                    LOG.warning(
                        "Attempted to delete path %s but it does "
                        "not exist.", path)
                elif 'Current file system invalid: VolumeNotFound' in e.stderr:
                    msg = _("Command to delete empty directory %s failed due "
                            "to context change.") % path
                    LOG.debug(msg)
                    raise exception.HNASSSCContextChange(msg=msg)
                else:
                    msg = _("Failed to delete directory %s.") % path
                    LOG.exception(msg)
                    raise exception.HNASBackendException(msg=msg)
Exemple #14
0
    def nfs_export_del(self, share_id=None, snapshot_id=None):
        if share_id is not None:
            name = os.path.join('/shares', share_id)
        elif snapshot_id is not None:
            name = os.path.join('/snapshots', snapshot_id)
        else:
            msg = _("NFS export not specified to delete.")
            raise exception.HNASBackendException(msg=msg)

        command = ['nfs-export', 'del', name]
        try:
            self._execute(command)
        except processutils.ProcessExecutionError as e:
            if 'does not exist' in e.stderr:
                LOG.warning("Export %s does not exist on "
                            "backend anymore.", name)
            else:
                msg = _("Could not delete NFS export %s.") % name
                LOG.exception(msg)
                raise exception.HNASBackendException(msg=msg)
Exemple #15
0
 def modify_quota(self, vvol_name, new_size):
     str_quota = six.text_type(new_size) + 'G'
     command = ['quota', 'mod', '--usage-limit', str_quota,
                self.fs_name, vvol_name]
     try:
         self._execute(command)
     except processutils.ProcessExecutionError:
         msg = _("Failed to update quota of vvol %(vvol)s to "
                 "%(quota)s.") % {'quota': str_quota, 'vvol': vvol_name}
         LOG.exception(msg)
         raise exception.HNASBackendException(msg=msg)
Exemple #16
0
 def vvol_create(self, vvol_name):
     # create a virtual-volume inside directory
     path = '/shares/' + vvol_name
     command = ['virtual-volume', 'add', '--ensure', self.fs_name,
                vvol_name, path]
     try:
         self._execute(command)
     except processutils.ProcessExecutionError:
         msg = _("Failed to create vvol %s.") % vvol_name
         LOG.exception(msg)
         raise exception.HNASBackendException(msg=msg)
Exemple #17
0
 def nfs_export_add(self, share_id):
     path = '/shares/' + share_id
     command = [
         'nfs-export', 'add', '-S', 'disable', '-c', '127.0.0.1', path,
         self.fs_name, path
     ]
     try:
         self._execute(command)
     except processutils.ProcessExecutionError:
         msg = _("Could not create NFS export %s.") % share_id
         LOG.exception(msg)
         raise exception.HNASBackendException(msg=msg)
Exemple #18
0
 def cifs_share_add(self, share_id):
     path = r'\\shares\\' + share_id
     command = [
         'cifs-share', 'add', '-S', 'disable', '--enable-abe',
         '--nodefaultsaa', share_id, self.fs_name, path
     ]
     try:
         self._execute(command)
     except processutils.ProcessExecutionError:
         msg = _("Could not create CIFS share %s.") % share_id
         LOG.exception(msg)
         raise exception.HNASBackendException(msg=msg)
Exemple #19
0
 def _check_vvol(self, vvol_name):
     command = [
         'virtual-volume', 'list', '--verbose', self.fs_name, vvol_name
     ]
     try:
         output, err = self._execute(command)
         return True
     except processutils.ProcessExecutionError as e:
         msg = six.text_type(e)
         LOG.exception(msg)
         msg = (_("Virtual volume %s does not exist.") % vvol_name)
         raise exception.HNASBackendException(msg=msg)
Exemple #20
0
 def quota_add(self, vvol_name, vvol_quota):
     str_quota = six.text_type(vvol_quota) + 'G'
     command = ['quota', 'add', '--usage-limit',
                str_quota, '--usage-hard-limit',
                'yes', self.fs_name, vvol_name]
     try:
         self._execute(command)
     except processutils.ProcessExecutionError:
         msg = _("Failed to add %(quota)s quota to vvol "
                 "%(vvol)s.") % {'quota': str_quota, 'vvol': vvol_name}
         LOG.exception(msg)
         raise exception.HNASBackendException(msg=msg)
Exemple #21
0
 def cifs_share_del(self, name):
     command = ['cifs-share', 'del', '--target-label', self.fs_name, name]
     try:
         self._execute(command)
     except processutils.ProcessExecutionError as e:
         if e.exit_code == 1:
             LOG.warning(
                 "CIFS share %s does not exist on "
                 "backend anymore.", name)
         else:
             msg = _("Could not delete CIFS share %s.") % name
             LOG.exception(msg)
             raise exception.HNASBackendException(msg=msg)
Exemple #22
0
 def nfs_export_del(self, share_id):
     path = '/shares/' + share_id
     command = ['nfs-export', 'del', path]
     try:
         self._execute(command)
     except processutils.ProcessExecutionError as e:
         if 'does not exist' in e.stderr:
             LOG.warning(_LW("Export %s does not exist on "
                             "backend anymore."), path)
         else:
             msg = six.text_type(e)
             LOG.exception(msg)
             raise exception.HNASBackendException(msg=msg)
Exemple #23
0
 def tree_delete(self, path):
     command = ['tree-delete-job-submit', '--confirm', '-f', self.fs_name,
                path]
     try:
         self._execute(command)
     except processutils.ProcessExecutionError as e:
         if 'Source path: Cannot access' in e.stderr:
             LOG.warning(_LW("Attempted to delete path %s "
                             "but it does not exist."), path)
         else:
             msg = _("Could not submit tree delete job to delete path "
                     "%s.") % path
             LOG.exception(msg)
             raise exception.HNASBackendException(msg=msg)
Exemple #24
0
 def vvol_delete(self, vvol_name):
     path = '/shares/' + vvol_name
     # Virtual-volume and quota are deleted together
     command = ['tree-delete-job-submit', '--confirm', '-f',
                self.fs_name, path]
     try:
         self._execute(command)
     except processutils.ProcessExecutionError as e:
         if 'Source path: Cannot access' in e.stderr:
             LOG.warning(_LW("Share %s does not exist."), vvol_name)
         else:
             msg = _("Failed to delete vvol %s.") % vvol_name
             LOG.exception(msg)
             raise exception.HNASBackendException(msg=msg)
Exemple #25
0
    def manage_existing(self, share, driver_options):
        """Manages a share that exists on backend.

        :param share: Share that will be managed.
        :param driver_options: Empty dict or dict with 'volume_id' option.
        :returns: Returns a dict with size of share managed
        and its location (your path in file-system).
        """
        share_id = self._get_hnas_share_id(share['id'])

        if share_id != share['id']:
            msg = _("Share ID %s already exists, cannot manage.") % share_id
            raise exception.HNASBackendException(msg=msg)

        LOG.info(
            _LI("Share %(shr_path)s will be managed with ID %(shr_id)s."), {
                'shr_path': share['export_locations'][0]['path'],
                'shr_id': share['id']
            })

        old_path_info = share['export_locations'][0]['path'].split(':')
        old_path = old_path_info[1].split('/')

        if len(old_path) == 3:
            evs_ip = old_path_info[0]
            share_id = old_path[2]
        else:
            msg = _("Incorrect path. It should have the following format: "
                    "IP:/shares/share_id.")
            raise exception.ShareBackendException(msg=msg)

        if evs_ip != self.hnas_evs_ip:
            msg = _("The EVS IP %(evs)s is not "
                    "configured.") % {
                        'evs': evs_ip
                    }
            raise exception.ShareBackendException(msg=msg)

        if self.backend_name not in share['host']:
            msg = _("The backend passed in the host parameter (%(shr)s) is "
                    "not configured.") % {
                        'shr': share['host']
                    }
            raise exception.ShareBackendException(msg=msg)

        output = self._manage_existing(share_id)
        self.private_storage.update(share['id'], {'hnas_id': share_id})

        return output
Exemple #26
0
 def cifs_share_del(self, share_id):
     command = [
         'cifs-share', 'del', '--target-label', self.fs_name, share_id
     ]
     try:
         self._execute(command)
     except processutils.ProcessExecutionError as e:
         if e.exit_code == 1:
             LOG.warning(
                 _LW("CIFS share %s does not exist on "
                     "backend anymore."), share_id)
         else:
             msg = six.text_type(e)
             LOG.exception(msg)
             raise exception.HNASBackendException(msg=msg)
Exemple #27
0
    def check_quota(self, vvol_name):
        command = ['quota', 'list', '--verbose', self.fs_name, vvol_name]
        try:
            output, err = self._execute(command)

        except processutils.ProcessExecutionError:
            msg = _("Could not check quota of vvol %s.") % vvol_name
            LOG.exception(msg)
            raise exception.HNASBackendException(msg=msg)

        if 'No quotas matching specified filter criteria' in output:
            msg = _("Virtual volume %s does not have any"
                    " quota.") % vvol_name
            LOG.error(msg)
            raise exception.HNASItemNotFoundException(msg=msg)
Exemple #28
0
    def nfs_export_add(self, share_id, snapshot_id=None):
        if snapshot_id is not None:
            path = os.path.join('/snapshots', share_id, snapshot_id)
            name = os.path.join('/snapshots', snapshot_id)
        else:
            path = name = os.path.join('/shares', share_id)

        command = ['nfs-export', 'add', '-S', 'disable', '-c', '127.0.0.1',
                   name, self.fs_name, path]
        try:
            self._execute(command)
        except processutils.ProcessExecutionError:
            msg = _("Could not create NFS export %s.") % name
            LOG.exception(msg)
            raise exception.HNASBackendException(msg=msg)
Exemple #29
0
 def cifs_share_add(self, share_id, snapshot_id=None):
     if snapshot_id is not None:
         path = r'\\snapshots\\' + share_id + r'\\' + snapshot_id
         name = snapshot_id
     else:
         path = r'\\shares\\' + share_id
         name = share_id
     command = ['cifs-share', 'add', '-S', 'disable', '--enable-abe',
                '--nodefaultsaa', name, self.fs_name, path]
     try:
         self._execute(command)
     except processutils.ProcessExecutionError:
         msg = _("Could not create CIFS share %s.") % name
         LOG.exception(msg)
         raise exception.HNASBackendException(msg=msg)
Exemple #30
0
    def get_share_quota(self, share_id):
        command = ['quota', 'list', self.fs_name, share_id]
        output, err = self._execute(command)

        quota = Quota(output)

        if quota.limit is None:
            return None

        if quota.limit_unit == 'TB':
            return quota.limit * units.Ki
        elif quota.limit_unit == 'GB':
            return quota.limit
        else:
            msg = (_("Share %s does not support quota values "
                     "below 1G.") % share_id)
            raise exception.HNASBackendException(msg=msg)