Cleans up data of failed attacks.

def cleanup_failed_attacks(self):
    """Cleans up data of failed attacks."""
    print_header('Cleaning up failed attacks')
    attacks_to_replace = {}
    self.attack_work.read_all_from_datastore()
    failed_submissions = set()
    error_msg = set()
    for k, v in iteritems(self.attack_work.work):
      if v['error'] is not None:
        attacks_to_replace[k] = dict(v)
        failed_submissions.add(v['submission_id'])
        error_msg.add(v['error'])
        attacks_to_replace[k].update(
            {
                'claimed_worker_id': None,
                'claimed_worker_start_time': None,
                'is_completed': False,
                'error': None,
                'elapsed_time': None,
            })
    self.attack_work.replace_work(attacks_to_replace)
    print('Affected submissions:')
    print(' '.join(sorted(failed_submissions)))
    print('Error messages:')
    print(' '.join(sorted(error_msg)))
    print('')
    inp = input_str('Are you sure? (type "yes" without quotes to confirm): ')
    if inp != 'yes':
      return
    self.attack_work.write_all_to_datastore()
    print('Work cleaned up')