Beispiel #1
0
 def _run_dog(self, command, subcommand, *params):
     cmd = ('env', 'LC_ALL=C', 'LANG=C', 'dog', command, subcommand, '-a',
            self.addr, '-p', self.port) + params
     try:
         return utils.execute(*cmd)
     except OSError as e:
         with excutils.save_and_reraise_exception():
             if e.errno == errno.ENOENT:
                 msg = _LE('Sheepdog is not installed. '
                           'OSError: command is %s.')
             else:
                 msg = _LE('OSError: command is %s.')
             LOG.error(msg, cmd)
     except processutils.ProcessExecutionError as e:
         _stderr = e.stderr
         if _stderr.startswith(self.DOG_RESP_CONNECTION_ERROR):
             reason = (_('Failed to connect to sheep daemon. '
                         'addr: %(addr)s, port: %(port)s'), {
                             'addr': self.addr,
                             'port': self.port
                         })
             raise exception.SheepdogError(reason=reason)
         raise exception.SheepdogCmdError(
             cmd=e.cmd,
             exit_code=e.exit_code,
             stdout=e.stdout.replace('\n', '\\n'),
             stderr=e.stderr.replace('\n', '\\n'))
Beispiel #2
0
    def backup_volume(self, context, backup, backup_service):
        """Create a new backup from an existing volume."""
        src_volume = self.db.volume_get(context, backup.volume_id)
        temp_snapshot_name = 'tmp-snap-%s' % src_volume.name

        # NOTE(tishizaki): If previous backup_volume operation has failed,
        # a temporary snapshot for previous operation may exist.
        # So, the old snapshot must be deleted before backup_volume.
        # Sheepdog 0.9 or later 'delete_snapshot' operation
        # is done successfully, although target snapshot does not exist.
        # However, sheepdog 0.8 or before 'delete_snapshot' operation
        # is failed, and raise ProcessExecutionError when target snapshot
        # does not exist.
        try:
            self.client.delete_snapshot(src_volume.name, temp_snapshot_name)
        except (exception.SheepdogCmdError):
            pass

        try:
            self.client.create_snapshot(src_volume.name, temp_snapshot_name)
        except (exception.SheepdogCmdError, OSError):
            msg = (_('Failed to create a temporary snapshot for volume %s.') %
                   src_volume.id)
            LOG.exception(msg)
            raise exception.SheepdogError(reason=msg)

        try:
            sheepdog_fd = SheepdogIOWrapper(self.addr, self.port, src_volume,
                                            temp_snapshot_name)
            backup_service.backup(backup, sheepdog_fd)
        finally:
            self.client.delete_snapshot(src_volume.name, temp_snapshot_name)
Beispiel #3
0
 def delete_snapshot(self, vdiname, snapname):
     try:
         (_stdout, _stderr) = self._run_dog('vdi', 'delete', '-s', snapname,
                                            vdiname)
         if _stderr.rstrip().endswith(self.DOG_RESP_SNAPSHOT_NOT_FOUND):
             LOG.warning(_LW('Snapshot "%s" not found.'), snapname)
         elif _stderr.rstrip().endswith(self.DOG_RESP_VDI_NOT_FOUND):
             LOG.warning(_LW('Volume "%s" not found.'), vdiname)
         elif _stderr.startswith(self.DOG_RESP_CONNECTION_ERROR):
             # NOTE(tishizaki)
             # Dog command does not return error_code although
             # dog command cannot connect to sheep process.
             # That is a Sheepdog's bug.
             # To avoid a Sheepdog's bug, now we need to check stderr.
             # If Sheepdog has been fixed, this check logic is needed
             # by old Sheepdog users.
             reason = (_('Failed to connect to sheep daemon. '
                         'addr: %(addr)s, port: %(port)s'), {
                             'addr': self.addr,
                             'port': self.port
                         })
             raise exception.SheepdogError(reason=reason)
     except exception.SheepdogCmdError as e:
         cmd = e.kwargs['cmd']
         _stderr = e.kwargs['stderr']
         with excutils.save_and_reraise_exception():
             LOG.error(_LE('Failed to delete snapshot. (command: %s)'), cmd)
Beispiel #4
0
    def check_cluster_status(self):
        try:
            (_stdout, _stderr) = self._run_dog('cluster', 'info')
        except exception.SheepdogCmdError as e:
            cmd = e.kwargs['cmd']
            _stderr = e.kwargs['stderr']
            with excutils.save_and_reraise_exception():
                if _stderr.startswith(self.DOG_RESP_CONNECTION_ERROR):
                    msg = _LE('Failed to connect to sheep daemon. '
                              'addr: %(addr)s, port: %(port)s')
                    LOG.error(msg, {'addr': self.addr, 'port': self.port})
                else:
                    LOG.error(_LE('Failed to check cluster status.'
                                  '(command: %s)'), cmd)

        if _stdout.startswith(self.DOG_RESP_CLUSTER_RUNNING):
            LOG.debug('Sheepdog cluster is running.')
            return

        reason = _('Invalid sheepdog cluster status.')
        if _stdout.startswith(self.DOG_RESP_CLUSTER_NOT_FORMATTED):
            reason = _('Cluster is not formatted. '
                       'You should probably perform "dog cluster format".')
        elif _stdout.startswith(self.DOG_RESP_CLUSTER_WAITING):
            reason = _('Waiting for all nodes to join cluster. '
                       'Ensure all sheep daemons are running.')
        raise exception.SheepdogError(reason=reason)
Beispiel #5
0
 def _run_dog(self, command, subcommand, *params):
     """Execute dog command wrapper."""
     addr = self.get_addr()
     cmd = ('env', 'LC_ALL=C', 'LANG=C', 'dog', command, subcommand, '-a',
            addr, '-p', self.port) + params
     try:
         (_stdout, _stderr) = utils.execute(*cmd)
         if _stderr.startswith(self.DOG_RESP_CONNECTION_ERROR):
             # NOTE(tishizaki)
             # Dog command does not return error_code although
             # dog command cannot connect to sheep process.
             # That is a Sheepdog's bug.
             # To avoid a Sheepdog's bug, now we need to check stderr.
             # If Sheepdog has been fixed, this check logic is needed
             # by old Sheepdog users.
             reason = (_('Failed to connect to sheep daemon. '
                         'addr: %(addr)s, port: %(port)s'), {
                             'addr': addr,
                             'port': self.port
                         })
             raise exception.SheepdogError(reason=reason)
         return (_stdout, _stderr)
     except OSError as e:
         with excutils.save_and_reraise_exception():
             if e.errno == errno.ENOENT:
                 msg = _LE('Sheepdog is not installed. '
                           'OSError: command is %s.')
             else:
                 msg = _LE('OSError: command is %s.')
             LOG.error(msg, cmd)
     except processutils.ProcessExecutionError as e:
         _stderr = e.stderr
         if _stderr.startswith(self.DOG_RESP_CONNECTION_ERROR):
             reason = (_('Failed to connect to sheep daemon. '
                         'addr: %(addr)s, port: %(port)s'), {
                             'addr': addr,
                             'port': self.port
                         })
             raise exception.SheepdogError(reason=reason)
         raise exception.SheepdogCmdError(
             cmd=e.cmd,
             exit_code=e.exit_code,
             stdout=e.stdout.replace('\n', '\\n'),
             stderr=e.stderr.replace('\n', '\\n'))
Beispiel #6
0
    def check_cluster_status(self):
        try:
            (_stdout, _stderr) = self._run_dog('cluster', 'info')
        except exception.SheepdogCmdError as e:
            cmd = e.kwargs['cmd']
            with excutils.save_and_reraise_exception():
                LOG.error('Failed to check cluster status.'
                          '(command: %s)', cmd)

        if _stdout.startswith(self.DOG_RESP_CLUSTER_RUNNING):
            LOG.debug('Sheepdog cluster is running.')
            return

        reason = _('Invalid sheepdog cluster status.')
        if _stdout.startswith(self.DOG_RESP_CLUSTER_NOT_FORMATTED):
            reason = _('Cluster is not formatted. '
                       'You should probably perform "dog cluster format".')
        elif _stdout.startswith(self.DOG_RESP_CLUSTER_WAITING):
            reason = _('Waiting for all nodes to join cluster. '
                       'Ensure all sheep daemons are running.')
        raise exception.SheepdogError(reason=reason)
Beispiel #7
0
 def _run_qemu_img(self, command, *params):
     """Executes qemu-img command wrapper."""
     addr = self.get_addr()
     cmd = ['env', 'LC_ALL=C', 'LANG=C', 'qemu-img', command]
     for param in params:
         if param.startswith(self.QEMU_SHEEPDOG_PREFIX):
             # replace 'sheepdog:vdiname[:snapshotname]' to
             #         'sheepdog:addr:port:vdiname[:snapshotname]'
             param = param.replace(
                 self.QEMU_SHEEPDOG_PREFIX,
                 '%(prefix)s%(addr)s:%(port)s:' % {
                     'prefix': self.QEMU_SHEEPDOG_PREFIX,
                     'addr': addr,
                     'port': self.port
                 }, 1)
         cmd.append(param)
     try:
         return utils.execute(*cmd)
     except OSError as e:
         with excutils.save_and_reraise_exception():
             if e.errno == errno.ENOENT:
                 msg = ('Qemu-img is not installed. OSError: command is '
                        '%(cmd)s.')
             else:
                 msg = 'OSError: command is %(cmd)s.'
             LOG.error(msg, {'cmd': tuple(cmd)})
     except processutils.ProcessExecutionError as e:
         _stderr = e.stderr
         if self.QEMU_IMG_RESP_CONNECTION_ERROR in _stderr:
             reason = (_('Failed to connect to sheep daemon. '
                         'addr: %(addr)s, port: %(port)s'), {
                             'addr': addr,
                             'port': self.port
                         })
             raise exception.SheepdogError(reason=reason)
         raise exception.SheepdogCmdError(
             cmd=e.cmd,
             exit_code=e.exit_code,
             stdout=e.stdout.replace('\n', '\\n'),
             stderr=e.stderr.replace('\n', '\\n'))