Exemplo n.º 1
0
 def _ensure_share_mounted(self, nfs_share):
     mnt_flags = []
     if self.shares.get(nfs_share) is not None:
         mnt_flags = self.shares[nfs_share].split()
     num_attempts = max(1, self.configuration.nfs_mount_attempts)
     for attempt in range(num_attempts):
         try:
             self._remotefsclient.mount(nfs_share, mnt_flags)
             return
         except Exception as e:
             if attempt == (num_attempts - 1):
                 LOG.error('Mount failure for %(share)s after '
                           '%(count)d attempts.',
                           {'share': nfs_share,
                            'count': num_attempts})
                 raise exception.NfsException(six.text_type(e))
             LOG.debug('Mount attempt %(attempt)d failed: %(exc)s.\n'
                       'Retrying mount ...',
                       {'attempt': attempt, 'exc': e})
             time.sleep(1)
Exemplo n.º 2
0
 def _do_clone_volume(self, src_vol, src_vol_name, tgt_vol):
     cnfs_share = src_vol.provider_location
     tgt_vol_name = tgt_vol.name
     tgt_vol_path = self._get_local_volume_path(cnfs_share, tgt_vol_name)
     src_vol_path = self._get_local_volume_path(cnfs_share, src_vol_name)
     tgt_vol_path_spl = tgt_vol_path + "::snap:vxfs:"
     self._execute('ln', src_vol_path, tgt_vol_path_spl, run_as_root=True)
     LOG.debug(
         "VeritasNFSDriver: do_clone_volume %(src_vol_path)s "
         "%(tgt_vol_path)s %(tgt_vol_path_spl)s", {
             'src_vol_path': src_vol_path,
             'tgt_vol_path_spl': tgt_vol_path_spl,
             'tgt_vol_path': tgt_vol_path
         })
     if not os.path.exists(tgt_vol_path):
         self._execute('rm', '-f', tgt_vol_path_spl, run_as_root=True)
         msg = _("Filesnap over NFS is not supported, "
                 "removing the ::snap:vxfs: file")
         LOG.error(msg)
         raise exception.NfsException(msg)
Exemplo n.º 3
0
    def _ensure_share_unmounted(self, nfs_share, mount_path=None):
        """Ensure that NFS share is unmounted on the host.

        :param nfs_share: NFS share name
        :param mount_path: mount path on the host
        """

        num_attempts = max(1, self.configuration.nfs_mount_attempts)

        if mount_path is None:
            mount_path = self._get_mount_point_for_share(nfs_share)

        if mount_path not in self._remotefsclient._read_mounts():
            LOG.info('NFS share %(share)s already unmounted from %(path)s.', {
                     'share': nfs_share,
                     'path': mount_path})
            return

        for attempt in range(num_attempts):
            try:
                self._execute('umount', mount_path, run_as_root=True)
                LOG.debug('NFS share %(share)s was successfully unmounted '
                          'from %(path)s.', {
                              'share': nfs_share,
                              'path': mount_path})
                return
            except Exception as e:
                msg = six.text_type(e)
                if attempt == (num_attempts - 1):
                    LOG.error('Unmount failure for %(share)s after '
                              '%(count)d attempts.', {
                                  'share': nfs_share,
                                  'count': num_attempts})
                    raise exception.NfsException(msg)
                LOG.warning('Unmount attempt %(attempt)d failed: %(msg)s. '
                            'Retrying unmount %(share)s from %(path)s.', {
                                'attempt': attempt,
                                'msg': msg,
                                'share': nfs_share,
                                'path': mount_path})
                greenthread.sleep(1)
Exemplo n.º 4
0
Arquivo: nfs.py Projeto: Jchuan/cinder
    def _ensure_share_mounted(self, nfs_share, mount_path=None):
        """Ensure that NFS share is mounted on the host.

        Unlike the parent method this one accepts mount_path as an optional
        parameter and uses it as a mount point if provided.

        :param nfs_share: NFS share name
        :param mount_path: mount path on the host
        """
        mnt_flags = []
        if self.shares.get(nfs_share) is not None:
            mnt_flags = self.shares[nfs_share].split()
        num_attempts = max(1, self.configuration.nfs_mount_attempts)
        for attempt in range(num_attempts):
            try:
                if mount_path is None:
                    self._remotefsclient.mount(nfs_share, mnt_flags)
                else:
                    if mount_path in self._remotefsclient._read_mounts():
                        LOG.info(_LI('Already mounted: %s'), mount_path)
                        return

                    self._execute('mkdir', '-p', mount_path,
                                  check_exit_code=False)
                    self._remotefsclient._mount_nfs(nfs_share, mount_path,
                                                    mnt_flags)
                return
            except Exception as e:
                if attempt == (num_attempts - 1):
                    LOG.error(_LE('Mount failure for %(share)s after '
                                  '%(count)d attempts.'), {
                              'share': nfs_share,
                              'count': num_attempts})
                    raise exception.NfsException(six.text_type(e))
                LOG.warning(
                    _LW('Mount attempt %(attempt)d failed: %(error)s. '
                        'Retrying mount ...'), {
                        'attempt': attempt,
                        'error': e})
                greenthread.sleep(1)
Exemplo n.º 5
0
    def do_setup(self, context):
        if not self.configuration.max_over_subscription_ratio > 0:
            msg = _("Config 'max_over_subscription_ratio' invalid. Must be > "
                    "0: %s") % self.configuration.max_over_subscription_ratio
            LOG.error(msg)
            raise exception.NfsException(msg)

        package = 'mount.nfs'
        try:
            self._execute(package, check_exit_code=False, run_as_root=True)
        except OSError as exc:
            if exc.errno == errno.ENOENT:
                msg = _('%s is not installed') % package
                raise exception.NfsException(msg)
            else:
                raise

        lcfg = self.configuration
        LOG.info(_LI('Connecting to host: %s.'), lcfg.san_ip)

        host = lcfg.san_ip
        user = lcfg.san_login
        password = lcfg.san_password
        https_port = lcfg.zfssa_https_port

        credentials = ['san_ip', 'san_login', 'san_password', 'zfssa_data_ip']

        for cred in credentials:
            if not getattr(lcfg, cred, None):
                exception_msg = _('%s not set in cinder.conf') % cred
                LOG.error(exception_msg)
                raise exception.CinderException(exception_msg)

        self.zfssa = factory_zfssa()
        self.zfssa.set_host(host, timeout=lcfg.zfssa_rest_timeout)

        auth_str = base64.encode_as_text('%s:%s' % (user, password))
        self.zfssa.login(auth_str)

        self.zfssa.create_project(lcfg.zfssa_nfs_pool, lcfg.zfssa_nfs_project,
                                  compression=lcfg.zfssa_nfs_share_compression,
                                  logbias=lcfg.zfssa_nfs_share_logbias)

        share_args = {
            'sharedav': 'rw',
            'sharenfs': 'rw',
            'root_permissions': '777',
            'compression': lcfg.zfssa_nfs_share_compression,
            'logbias': lcfg.zfssa_nfs_share_logbias
        }

        self.zfssa.create_share(lcfg.zfssa_nfs_pool, lcfg.zfssa_nfs_project,
                                lcfg.zfssa_nfs_share, share_args)

        share_details = self.zfssa.get_share(lcfg.zfssa_nfs_pool,
                                             lcfg.zfssa_nfs_project,
                                             lcfg.zfssa_nfs_share)

        mountpoint = share_details['mountpoint']

        self.mount_path = lcfg.zfssa_data_ip + ':' + mountpoint
        https_path = 'https://' + lcfg.zfssa_data_ip + ':' + https_port + \
            '/shares' + mountpoint

        LOG.debug('NFS mount path: %s', self.mount_path)
        LOG.debug('WebDAV path to the share: %s', https_path)

        self.shares = {}
        mnt_opts = self.configuration.zfssa_nfs_mount_options
        self.shares[self.mount_path] = mnt_opts if len(mnt_opts) > 1 else None

        # Initialize the WebDAV client
        self.zfssa.set_webdav(https_path, auth_str)

        # Edit http service so that WebDAV requests are always authenticated
        args = {'https_port': https_port,
                'require_login': True}

        self.zfssa.modify_service('http', args)
        self.zfssa.enable_service('http')

        if lcfg.zfssa_enable_local_cache:
            LOG.debug('Creating local cache directory %s.',
                      lcfg.zfssa_cache_directory)
            self.zfssa.create_directory(lcfg.zfssa_cache_directory)
Exemplo n.º 6
0
    def _copy_volume_from_snapshot(self, snapshot, volume, volume_size,
                                   src_encryption_key_id=None,
                                   new_encryption_key_id=None):
        """Copy data from snapshot to destination volume.

        This is done with a qemu-img convert to raw/qcow2 from the snapshot
        qcow2.
        """

        LOG.debug("Copying snapshot: %(snap)s -> volume: %(vol)s, "
                  "volume_size: %(size)s GB",
                  {'snap': snapshot.id,
                   'vol': volume.id,
                   'size': volume_size})

        info_path = self._local_path_volume_info(snapshot.volume)
        snap_info = self._read_info_file(info_path)
        vol_path = self._local_volume_dir(snapshot.volume)
        forward_file = snap_info[snapshot.id]
        forward_path = os.path.join(vol_path, forward_file)

        # Find the file which backs this file, which represents the point
        # when this snapshot was created.
        img_info = self._qemu_img_info(forward_path, snapshot.volume.name)
        path_to_snap_img = os.path.join(vol_path, img_info.backing_file)

        path_to_new_vol = self._local_path_volume(volume)

        LOG.debug("will copy from snapshot at %s", path_to_snap_img)

        if self.configuration.nfs_qcow2_volumes:
            out_format = 'qcow2'
        else:
            out_format = 'raw'

        if new_encryption_key_id is not None:
            if src_encryption_key_id is None:
                message = _("Can't create an encrypted volume %(format)s "
                            "from an unencrypted source."
                            ) % {'format': out_format}
                LOG.error(message)
                # TODO(enriquetaso): handle unencrypted snap->encrypted vol
                raise exception.NfsException(message)
            keymgr = key_manager.API(CONF)
            new_key = keymgr.get(volume.obj_context, new_encryption_key_id)
            new_passphrase = \
                binascii.hexlify(new_key.get_encoded()).decode('utf-8')

            # volume.obj_context is the owner of this request
            src_key = keymgr.get(volume.obj_context, src_encryption_key_id)
            src_passphrase = \
                binascii.hexlify(src_key.get_encoded()).decode('utf-8')

            tmp_dir = volume_utils.image_conversion_dir()
            with tempfile.NamedTemporaryFile(prefix='luks_',
                                             dir=tmp_dir) as src_pass_file:
                with open(src_pass_file.name, 'w') as f:
                    f.write(src_passphrase)

                with tempfile.NamedTemporaryFile(prefix='luks_',
                                                 dir=tmp_dir) as new_pass_file:
                    with open(new_pass_file.name, 'w') as f:
                        f.write(new_passphrase)

                    image_utils.convert_image(
                        path_to_snap_img,
                        path_to_new_vol,
                        'luks',
                        passphrase_file=new_pass_file.name,
                        src_passphrase_file=src_pass_file.name,
                        run_as_root=self._execute_as_root)
        else:
            image_utils.convert_image(path_to_snap_img,
                                      path_to_new_vol,
                                      out_format,
                                      run_as_root=self._execute_as_root)

        self._set_rw_permissions_for_all(path_to_new_vol)