Пример #1
0
def run(environ, executor, safe_check=True):
    """
    Common code for executors.

    :param: environ Recipe to pass to `filetracker` and `sio.workers.executors`
                    For all supported options, see the global documentation for
                    `sio.workers.executors`.
    :param: executor Executor instance used for executing commands.
    :param: safe_check Enables safe checking output corectness.
                       See `sio.executors.checkers`. True by default.
    """
    ft.download(environ, 'exe_file', 'exe', add_to_cache=True)
    os.chmod('exe', 0700)
    ft.download(environ, 'in_file', 'in', add_to_cache=True)

    with executor as e:
        with open('in', 'rb') as inf:
            with open('out', 'wb') as outf:
                renv = e(['./exe'], stdin=inf, stdout=outf, ignore_errors=True,
                            environ=environ)

    _populate_environ(renv, environ)

    if renv['result_code'] == 'OK' and environ.get('check_output'):
        environ = checker.run(environ, no_sandbox=not safe_check)

    if 'out_file' in environ:
        ft.upload(environ, 'out_file', 'out',
            to_remote_store=environ.get('upload_out', False))

    return environ
Пример #2
0
def run(environ, executor, use_sandboxes=True):
    """
    Common code for executors.

    :param: environ Recipe to pass to `filetracker` and `sio.workers.executors`
                    For all supported options, see the global documentation for
                    `sio.workers.executors` and prefix them with ``exec_``.
    :param: executor Executor instance used for executing commands.
    :param: use_sandboxes Enables safe checking output correctness.
                       See `sio.executors.checkers`. True by default.
    """
    input_name = tempcwd('in')

    file_executor = get_file_runner(executor, environ)
    exe_filename = file_executor.preferred_filename()

    ft.download(environ, 'exe_file', exe_filename, add_to_cache=True)
    os.chmod(tempcwd(exe_filename), 0700)
    ft.download(environ, 'in_file', input_name, add_to_cache=True)

    zipdir = tempcwd('in_dir')
    os.mkdir(zipdir)
    try:
        if is_zipfile(input_name):
            try:
                # If not a zip file, will pass it directly to exe
                with ZipFile(tempcwd('in'), 'r') as f:
                    if len(f.namelist()) != 1:
                        raise Exception("Archive should have only one file.")

                    f.extract(f.namelist()[0], zipdir)
                    input_name = os.path.join(zipdir, f.namelist()[0])
            # zipfile throws some undocumented exceptions
            except Exception as e:
                raise StandardError("Failed to open archive: " + unicode(e))

        with file_executor as fe:
            with open(input_name, 'rb') as inf:
                with open(tempcwd('out'), 'wb') as outf:
                    renv = fe(tempcwd(exe_filename), [],
                              stdin=inf, stdout=outf, ignore_errors=True,
                              environ=environ, environ_prefix='exec_')

        _populate_environ(renv, environ)

        if renv['result_code'] == 'OK' and environ.get('check_output'):
            environ = checker.run(environ, use_sandboxes=use_sandboxes)

        for key in ('result_code', 'result_string'):
            environ[key] = replace_invalid_UTF(environ[key])

        if 'out_file' in environ:
            ft.upload(environ, 'out_file', tempcwd('out'),
                to_remote_store=environ.get('upload_out', False))
    finally:
        rmtree(zipdir)

    return environ
Пример #3
0
def run(environ):
    exe_file = ft.download(environ, 'exe_file', 'exe', add_to_cache=True)
    os.chmod(exe_file, 0700)
    in_file = ft.download(environ, 'in_file', 'in', add_to_cache=True)

    if 'exec_time_limit' in environ:
        time_limit = environ['exec_time_limit']
        time_ulimit = (time_limit + 999) / 1000
    else:
        time_limit = time_ulimit = None
    if 'exec_mem_limit' in environ:
        mem_limit = environ['exec_mem_limit'] / 1024
    else:
        mem_limit = None

    retcode, output = execute(['bash', '-c', 'time ./exe < in > out'],
        time_limit=time_ulimit, mem_limit=mem_limit, ignore_errors=True)

    time_output_matches = TIME_OUTPUT_RE.findall(output)
    if time_output_matches:
        mins, secs = time_output_matches[-1]
        time_used = int((int(mins) * 60 + float(secs)) * 1000)
    else:
        raise RuntimeError('Could not find output of time program. '
            'Captured output: %s' % output)

    if time_limit is not None and time_used >= 0.99 * time_limit:
        environ['result_string'] = 'time limit exceeded'
        environ['result_code'] = 'TLE'
    elif retcode == 0:
        environ['result_string'] = 'ok'
        environ['result_code'] = 'OK'
    else:
        environ['result_string'] = 'program exited with code %d' % retcode
        environ['result_code'] = 'RE'
    environ['time_used'] = time_used
    environ['exectime_used'] = 0
    environ['mem_used'] = 0
    environ['num_syscalls'] = 0

    if environ['result_code'] == 'OK' and environ.get('check_output'):
        environ = checker.run(environ, no_sandbox=True)

    if 'out_file' in environ:
        ft.upload(environ, 'out_file', 'out',
            to_remote_store=environ.get('upload_out', False))

    return environ
Пример #4
0
def run(environ):
    exe_file = ft.download(environ, 'exe_file', 'exe', add_to_cache=True)
    os.chmod(exe_file, 0700)
    in_file = ft.download(environ, 'in_file', 'in', add_to_cache=True)
    env = os.environ.copy()
    for key, default in _options:
        value = environ.get('exec_' + key.lower(), default)
        env[key] = value

    with get_sandbox('vcpu_exec-sandbox') as sandbox:
        retcode, output = execute(
                [os.path.join(sandbox.path, 'pin-supervisor/supervisor-bin/',
                        'supervisor'), '-f', '3',
                    '--', './exe',
                    noquote('<'), 'in', noquote('3>'), 'supervisor_result',
                    noquote('>'), 'out'], env=env)

    result_file = open('supervisor_result')
    status_line = result_file.readline().strip().split()
    environ['result_string'] = result_file.readline().strip()
    result_file.close()

    for num, key in enumerate((None, 'result_code', 'time_used',
            'exectime_used', 'mem_used', 'num_syscalls')):
        if key:
            environ[key] = int(status_line[num])
    result_code = _supervisor_result_to_code(environ['result_code'])
    environ['result_code'] = result_code

    if result_code == 'OK' and environ.get('check_output'):
        environ = checker.run(environ)

    if 'out_file' in environ:
        ft.upload(environ, 'out_file', 'out',
            to_remote_store=environ.get('upload_out', False))

    return environ
Пример #5
0
                    '-f', '3', '--', './exe',
                    noquote('<'), 'in', noquote('3>'), 'supervisor_result',
                    noquote('>'), 'out'], env=env)

    result_file = open('supervisor_result')
    status_line = result_file.readline().strip().split()
    environ['result_string'] = result_file.readline().strip()
    result_file.close()

    try:
        for num, key in enumerate((None, 'result_code', 'time_used',
                'exectime_used', 'mem_used', 'num_syscalls')):
            if key:
                environ[key] = int(status_line[num])
        result_code = _supervisor_result_to_code(environ['result_code'])
    except Exception, e:
        result_code = 'SE'
        for i in ('time_used', 'exectime_used', 'mem_used', 'num_syscalls'):
            environ.setdefault(i, 0)
        environ['result_string'] = str(e)

    environ['result_code'] = result_code
    if result_code == 'OK' and environ.get('check_output'):
        environ = checker.run(environ)

    if 'out_file' in environ:
        ft.upload(environ, 'out_file', 'out',
            to_remote_store=environ.get('upload_out', False))

    return environ
Пример #6
0
def run(environ, executor, use_sandboxes=True):
    """
    Common code for executors.

    :param: environ Recipe to pass to `filetracker` and `sio.workers.executors`
                    For all supported options, see the global documentation for
                    `sio.workers.executors` and prefix them with ``exec_``.
    :param: executor Executor instance used for executing commands.
    :param: use_sandboxes Enables safe checking output correctness.
                       See `sio.executors.checkers`. True by default.
    """
    input_name = tempcwd('in')

    file_executor = get_file_runner(executor, environ)
    exe_filename = file_executor.preferred_filename()

    ft.download(environ, 'exe_file', exe_filename, add_to_cache=True)
    os.chmod(tempcwd(exe_filename), 0o700)
    ft.download(environ, 'in_file', input_name, add_to_cache=True)

    zipdir = tempcwd('in_dir')
    os.mkdir(zipdir)
    try:
        if is_zipfile(input_name):
            try:
                # If not a zip file, will pass it directly to exe
                with ZipFile(tempcwd('in'), 'r') as f:
                    if len(f.namelist()) != 1:
                        raise Exception("Archive should have only one file.")

                    f.extract(f.namelist()[0], zipdir)
                    input_name = os.path.join(zipdir, f.namelist()[0])
            # zipfile throws some undocumented exceptions
            except Exception as e:
                raise Exception("Failed to open archive: " + six.text_type(e))

        with file_executor as fe:
            with open(input_name, 'rb') as inf:
                # Open output file in append mode to allow appending
                # only to the end of the output file. Otherwise,
                # a contestant's program could modify the middle of the file.
                with open(tempcwd('out'), 'ab') as outf:
                    renv = fe(tempcwd(exe_filename), [],
                              stdin=inf,
                              stdout=outf,
                              ignore_errors=True,
                              environ=environ,
                              environ_prefix='exec_')

        _populate_environ(renv, environ)

        if renv['result_code'] == 'OK' and environ.get('check_output'):
            environ = checker.run(environ, use_sandboxes=use_sandboxes)

        for key in ('result_code', 'result_string'):
            environ[key] = replace_invalid_UTF(environ[key])

        if 'out_file' in environ:
            ft.upload(environ,
                      'out_file',
                      tempcwd('out'),
                      to_remote_store=environ.get('upload_out', False))
    finally:
        rmtree(zipdir)

    return environ
Пример #7
0
def run(environ, executor, use_sandboxes=True):
    """
    Common code for executors.

    :param: environ Recipe to pass to `filetracker` and `sio.workers.executors`
                    For all supported options, see the global documentation for
                    `sio.workers.executors` and prefix them with ``exec_``.
    :param: executor Executor instance used for executing commands.
    :param: use_sandboxes Enables safe checking output correctness.
                       See `sio.executors.checkers`. True by default.
    """

    if feedback.judge_prepare(environ).force_not_judge:
        environ['time_used'] = 0
        environ['result_string'] = 'not judged'
        environ['result_code'] = 'NJ'
        environ['mem_used'] = 0
        environ['num_syscalls'] = 0
        environ['stderr'] = ''
        return environ

    input_name = tempcwd('in')

    file_executor = get_file_runner(executor, environ)
    exe_filename = file_executor.preferred_filename()

    ft.download(environ, 'exe_file', exe_filename, add_to_cache=True)
    os.chmod(tempcwd(exe_filename), 0700)
    ft.download(environ, 'in_file', input_name, add_to_cache=True)

    zipdir = tempcwd('in_dir')
    os.mkdir(zipdir)
    try:
        if is_zipfile(input_name):
            try:
                # If not a zip file, will pass it directly to exe
                with ZipFile(tempcwd('in'), 'r') as f:
                    if len(f.namelist()) != 1:
                        raise Exception("Archive should have only one file.")

                    f.extract(f.namelist()[0], zipdir)
                    input_name = os.path.join(zipdir, f.namelist()[0])
            # zipfile throws some undocumented exceptions
            except Exception as e:
                raise StandardError("Failed to open archive: " + unicode(e))

        with file_executor as fe:
            with open(input_name, 'rb') as inf:
                with open(tempcwd('out'), 'wb') as outf:
                    feedback.judge_started(environ)
                    renv = fe(tempcwd(exe_filename), [],
                              stdin=inf,
                              stdout=outf,
                              ignore_errors=True,
                              environ=environ,
                              environ_prefix='exec_')

        _populate_environ(renv, environ)

        if renv['result_code'] == 'OK' and environ.get('check_output'):
            environ = checker.run(environ, use_sandboxes=use_sandboxes)

        for key in ('result_code', 'result_string'):
            environ[key] = replace_invalid_UTF(environ[key])
        feedback.judge_finished(environ)

        if 'out_file' in environ:
            ft.upload(environ,
                      'out_file',
                      tempcwd('out'),
                      to_remote_store=environ.get('upload_out', False))
    finally:
        rmtree(zipdir)

    return environ