def test_executor_in_docker(): import epicbox PROFILES = { 'python': { 'docker_image': 'python:3.8-alpine', 'network_disabled': True, 'user': '******' } } epicbox.configure(profiles=PROFILES) files = [{ 'name': 'executor.py', 'content': resource_string('aleph.vms.dockerized', 'tools/executor.py') }] limits = {'cputime': 2, 'memory': 256} example_code = resource_string('aleph.vms.dockerized', 'tools/example.py') payload = { 'code': example_code.decode('utf-8'), 'action': 'call', 'function': 'transfer', 'message': { 'sender': 'NULSd6HgcNwprmEYbQ7pqLznGVU3EhW7Syv7W' }, 'state': { "owner": "NULSd6HgcNwprmEYbQ7pqLznGVU3EhW7Syv7W", "name": "Test", "symbol": "TST", "decimals": 18, "total_supply": 24000000000000000000000000, "balances": { "NULSd6HgcNwprmEYbQ7pqLznGVU3EhW7Syv7W": 24000000000000000000000000 }, "allowed": {} }, 'args': ['blah', 1000 * (10**18)] } output = epicbox.run('python', 'python3 executor.py', files=files, limits=limits, stdin=json.dumps(payload).encode('utf-8')) out_payload = json.loads(output['stdout'].decode('utf-8')) assert out_payload['result'] is True assert out_payload['state'][ 'owner'] == 'NULSd6HgcNwprmEYbQ7pqLznGVU3EhW7Syv7W' assert out_payload['state']['total_supply'] == 24000000 * (10**18) assert out_payload['state']['balances'][ 'NULSd6HgcNwprmEYbQ7pqLznGVU3EhW7Syv7W'] == (24000000 - 1000) * (10** 18) assert out_payload['state']['balances']['blah'] == 1000 * (10**18) assert len(out_payload['state']['balances']) == 2 assert not output.get('stderr')
def configure_docker(): """Function used to configure base profile.""" profiles = [ epicbox.Profile("linter", "epicbox-linter:latest"), epicbox.Profile("formatter", "epicbox-formatter:latest"), ] epicbox.configure(profiles=profiles)
def configure(profile, profile_read_only, profile_unknown_image, docker_url): epicbox.configure( profiles=[profile, profile_read_only, profile_unknown_image], docker_url=docker_url) # Standard logging to console console = logging.StreamHandler() logging.getLogger().addHandler(console)
def python(code: str, testcase_dir: str) -> SubmissionResult: files = [{'name': 'main.py', 'content': code}] result = SubmissionResult() epicbox.configure( profiles=[epicbox.Profile('python', 'python:3.6.5-alpine')]) test_no = 0 while test_no < MAX_NUMBER_OF_TESTCASES: stdin, expected = get_input_expected_output(testcase_dir, test_no) if stdin == None or expected == None: break output = epicbox.run('python', 'python3 main.py', stdin=stdin, files=files, limits=limits['py']) process_output(test_no, output, expected, result) test_no += 1 return result
def translate_keras(filename): """Translate a keras model defined in a file into the neural network graph. Arguments: filename {String} -- name of the file to be translated Returns: object -- the result of this translation, can be an error """ if keras_ext in filename: try: return graph_from_model_file(filename) except Exception as err: return { 'error_class': '', 'line_number': 1, 'detail': "Model could not be loaded correctly. Error: " + str(err) } else: epicbox.configure( profiles=[epicbox.Profile('python', 'tf_plus_keras:latest')]) general_reader = open('translate/keras_loader.txt', 'rb') general_code = general_reader.read() with open(filename, 'rb') as myfile: keras_code = myfile.read() try: return graph_from_external_file(keras_code, general_code) except Exception as err: return { 'error_class': '', 'line_number': 1, 'detail': str(err) }
def configure(profile, profile_read_only, docker_url): epicbox.configure(profiles=[profile, profile_read_only], docker_url=docker_url) structlog.configure( processors=[ structlog.processors.TimeStamper(fmt='iso'), structlog.processors.KeyValueRenderer(key_order=['event']), ], logger_factory=structlog.PrintLoggerFactory(), )
def cpp(code: str, testcase_dir: str) -> SubmissionResult: files = [{'name': 'main.cpp', 'content': code}] result = SubmissionResult() PROFILES = { 'gcc_compile': { 'docker_image': 'stepik/epicbox-gcc:6.3.0', 'user': '******', }, 'gcc_run': { 'docker_image': 'stepik/epicbox-gcc:6.3.0', # It's safer to run untrusted code as a non-root user (even in a container) 'user': '******', 'read_only': True, 'network_disabled': True, } } epicbox.configure(profiles=PROFILES) test_no = 0 with epicbox.working_directory() as workdir: compilation_output = epicbox.run('gcc_compile', 'g++ -std=c++14 -O2 -o main main.cpp', files=files, workdir=workdir) if compilation_output['exit_code'] != 0: result.add_testcase_verdict(test_no, False, Verdict.COMPILATION_ERROR, 0) result.add_log(compilation_output['stderr']) return result while test_no < MAX_NUMBER_OF_TESTCASES: stdin, expected = get_input_expected_output(testcase_dir, test_no) if stdin == None or expected == None: break output = epicbox.run('gcc_run', './main', stdin=stdin, limits=limits['cpp'], workdir=workdir) process_output(test_no, output, expected, result) test_no += 1 return result
def post(self, request): """Post method to execute code.""" serializer = CodeSerializerExercise(data=request.data) if serializer.is_valid(): main_code = render_main(serializer.validated_data["code_input"], ) exercise = get_object_or_404( Exercise, id=serializer.validated_data["exercise_id"], ) epicbox.configure(profiles=[ epicbox.Profile( exercise.docker_image.profile_name, exercise.docker_image.image_name, ), ]) result_run1 = docker_run( exercise.docker_image.profile_name, "python {0}".format(serializer.validated_data["filename"]), files=[ { "name": serializer.validated_data["filename"], "content": main_code.encode(), }, ], limits={ "cputime": 50, "memory": 128 }, ) errors_set = set() for template in exercise.errors_template.all(): for error in template.errors.all().distinct().values_list( "code", flat=True): errors_set.add(error) if len(errors_set) > 0: errors_string = " ".join(errors_set) else: errors_string = None result_run2 = lint(serializer, errors_string) result_run1["lint_results"] = result_run2["lint_results"] create_submission.delay( self.request.user.mail, serializer.validated_data["exercise_id"], serializer.validated_data["code_input"], result_run1, serializer.validated_data["final"], ) return Response(result_run1, status=status.HTTP_200_OK) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def _configure_executor(): # The following is a "HACK" so we can use the defaults without specifying limits # each time. epicbox also uses /sandbox for its DOCKER_WORKDIR which does not have # the correct permissions for user handin execution_timeout = int(const.PROGRAM_EXECUTION_TIMEOUT) memory_limit = int(const.PROGRAM_MEMORY_LIMIT) epicbox.config.DEFAULT_LIMITS = { 'cputime': execution_timeout, 'realtime': execution_timeout, 'memory': memory_limit, 'processes': -1 } epicbox.config.DOCKER_WORKDIR = "/home/handin" epicbox.configure(profiles=PROFILES)
def configure(docker_url): epicbox.configure( profiles=[ epicbox.Profile('python3', 'stepic/epicbox-python', user='******', read_only=True), epicbox.Profile('gcc', 'stepik/epicbox-gcc:5.3.0'), ], docker_url=docker_url, ) structlog.configure( processors=[ structlog.processors.TimeStamper(fmt='iso'), structlog.processors.KeyValueRenderer(key_order=['event']), ], logger_factory=structlog.PrintLoggerFactory(), )
def build_tests(workdir): config = validate_work_config(workdir) if config['language'] == 'c': compiler = 'gcc' else: compiler = 'g++' with epicbox.working_directory() as wd: epicbox.configure(profiles=PROFILES) if config['type'] == 'multiple': for exercise in config['exercises']: if 'reference' in exercise['tests']: build_each(exercise, compiler, wd) else: if 'reference' not in config['tests']: print('REFERENCE IS NOT DEFINED FOR CONFIG') else: build_each(config, compiler, wd)
def makeProfiles(self, user = "******"): self.PROFILES = { 'compile': { 'docker_image': self.compiler_info['docker_image'], 'user': '******', }, 'run': { 'docker_image': self.compiler_info['docker_image'], 'user': user, 'read_only': True, 'network_disabled': False }, 'directRun': { 'docker_image': self.compiler_info['docker_image'] } } epicbox.configure(profiles=self.PROFILES)
def run(code, lang): epicbox.configure(profiles=PROFILES) with epicbox.working_directory() as workdir: if lang == 'python': result = epicbox.run( 'python', 'python3 main.py', files=[{ 'name': 'main.py', 'content': code }], limits=LIMITS, workdir=workdir, ) elif lang == 'text/x-java': compile_result = epicbox.run( 'java_compile', 'javac Main.java', files=[{ 'name': 'Main.java', 'content': code }], limits=LIMITS, workdir=workdir, ) if compile_result['exit_code'] != 0: return compile_result else: result = epicbox.run( 'java_run', 'java Main', files=[{ 'name': 'Main.java', 'content': code }], limits=LIMITS, workdir=workdir, ) else: return 'FATAL: Language Unsupported' return result
def __init__(self, grader_root='/tmp/', fork_per_item=True, logger_name=__name__, fail_on_error=False, alert_mail=None): """ grader_root = root path to graders fork_per_item = fork a process for every request logger_name = name of logger alert_mail = SMTP credentials and recipients list """ self.log = logging.getLogger(logger_name) self.grader_root = path(grader_root) self.fork_per_item = fork_per_item self.fail_on_error = fail_on_error self.alert_mail = alert_mail if check_mail(alert_mail, self.log) else None epicbox.configure(profiles=[ epicbox.Profile('python', 'python:3.7-alpine'), epicbox.Profile('python-server', 'python-server:1.0'), ]) self.server_files = [ {"name": "main.py", "content": get_server_file("main.py")}, {"name": "helper.py", "content": get_server_file("helper.py")}, ]
epicbox.configure({ 'asm64_compile': { 'docker_image': 'strellic/epicbox-asm64:latest', 'user': '******' }, 'asm64_run': { 'docker_image': 'strellic/epicbox-asm64:latest', 'user': '******', }, 'gcc_compile': { 'docker_image': 'stepik/epicbox-gcc:6.3.0', 'user': '******' }, 'gcc_run': { 'docker_image': 'stepik/epicbox-gcc:6.3.0', 'user': '******', }, 'mono_compile': { 'docker_image': 'stepik/epicbox-mono:5.0.0', 'user': '******' }, 'mono_run': { 'docker_image': 'stepik/epicbox-mono:5.0.0', 'user': '******', }, 'java_compile': { 'docker_image': 'stepik/epicbox-java:11.0.1', 'user': '******' }, 'java_run': { 'docker_image': 'stepik/epicbox-java:11.0.1', 'user': '******', }, 'node_run': { 'docker_image': 'strellic/epicbox-node:latest', 'user': '******', }, 'python_run': { 'docker_image': 'strellic/epicbox-python:latest', 'user': '******', } })
"user": "******", }, "gcc_run": { "docker_image": "stepik/epicbox-gcc:6.3.0", "user": "******", "read_only": True, "network_disabled": False, }, "java": { "docker_image": "stepik/epicbox-java:11.0.1", }, "python": { "docker_image": "python:3.6.5-alpine", }, } epicbox.configure(profiles=PROFILES) def execute_cpp(untrusted_code, input_values, limits): result = [] with epicbox.working_directory() as workdir: value = epicbox.run( "gcc_compile", "g++ -pipe -O2 -static -o main main.cpp", files=[{ "name": "main.cpp", "content": untrusted_code }], workdir=workdir, ) if value["stderr"]:
from flask_cors import CORS from flask_pymongo import PyMongo from psypl.experiments import EXPERIMENTS from bson import json_util import epicbox app = Flask(__name__) CORS(app) app.debug = True app.config[ "MONGO_URI"] = "mongodb://*****:*****@localhost:27017/experiments?authSource=admin" mongo = PyMongo(app) experiments_db = mongo.db.experiments epicbox.configure(profiles=[epicbox.Profile('rust', 'rust')]) def get_experiment(name): name = ''.join(name.split('_') + ['experiment']) cls = [e for e in EXPERIMENTS if e.__name__.lower() == name][0] return cls() @app.route("/") def index(): return render_template('index.html', experiments=[{ 'url': '_'.join([s.lower() for s in e.name_parts()]), 'name':
import epicbox epicbox.configure( profiles=[ epicbox.Profile('python', 'czentye/matplotlib-minimal') ] ) files = [{'name': 'main.py', 'content': b'x = input(); print(x); y = input(); print("Hi " + y)'}] limits = {'cputime': 10, 'memory': 64} result = epicbox.run('python', 'python3 -u main.py', stdin=b'x\nalex\n', files=files, limits=limits) print(result)
from xblockutils.resources import ResourceLoader from xblockutils.studio_editable import StudioEditableXBlockMixin from xmodule.contentstore.content import StaticContent from nand2tetris.utils import (file_contents_iter, get_file_modified_time_utc, get_file_storage_path, get_sha1) from nand2tetris.tasks import (get_zip_file_name, get_zip_file_path, zip_student_submissions) log = logging.getLogger(__name__) loader = ResourceLoader(__name__) ITEM_TYPE = "nand2tetrisxblock" epicbox.configure(profiles=[ epicbox.Profile('nand2tetris', 'tcarreira/nand2tetris-autograder:2.6.1-epicbox') ]) limits = {'cputime': 1, 'memory': 64} def reify(meth): """ Decorator which caches value so it is only computed once. Keyword arguments: inst """ def getter(inst): """ Set value to meth name in dict and returns value. """ value = meth(inst)
else: from .local import * if LOGGING_CONFIGURE: logging.config.dictConfig(LOGGING) logging.captureWarnings(True) structlog.configure( processors=[ structlog.stdlib.filter_by_level, structlog.stdlib.add_logger_name, structlog.stdlib.add_log_level, structlog.stdlib.PositionalArgumentsFormatter(), log.add_supervisor_instance_id, structlog.processors.TimeStamper(fmt='iso'), structlog.processors.StackInfoRenderer(), structlog.processors.format_exc_info, structlog.processors.JSONRenderer() if LOGGING_JSON else structlog.processors.KeyValueRenderer(key_order=['event']), ], logger_factory=structlog.stdlib.LoggerFactory(), wrapper_class=structlog.stdlib.BoundLogger, cache_logger_on_first_use=True, ) epicbox.configure(dict(EPICBOX_BASE_PROFILES, **EPICBOX_PROFILES), base_workdir=EPICBOX_BASE_WORKDIR, docker_url=EPICBOX_DOCKER_URL) configure_jail_code(sys.modules[__name__])
def initialize(cls): epicbox.configure(profiles=cls.PROFILES)
import epicbox epicbox.configure(profiles=[ # epicbox.Profile('python', 'python:3.6.5-alpine') epicbox.Profile('python', 'continuumio/anaconda3:latest') ]) class ResponseWrapper: def __init__(self, exit_code: int, stdout: bytes, stderr: bytes, duration: float, timeout: bool, oom_killed: bool): self.exit_code = exit_code self.output: str = stdout.decode("ascii") self.stderr: bytes = stderr.decode("ascii") self.duration: bytes = duration self.timeout: float = timeout self.oom_killed: bool = oom_killed def getProcessResponse(content: bytes): files = [{'name': 'main.py', 'content': content}] limits = {'cputime': 1, 'memory': 64} result = epicbox.run('python', 'python3 main.py', files=files, limits=limits) return ResponseWrapper(**result)
from .local import * if LOGGING_CONFIGURE: logging.config.dictConfig(LOGGING) logging.captureWarnings(True) structlog.configure( processors=[ structlog.stdlib.filter_by_level, structlog.stdlib.add_logger_name, structlog.stdlib.add_log_level, structlog.stdlib.PositionalArgumentsFormatter(), log.add_supervisor_instance_id, structlog.processors.TimeStamper(fmt='iso'), structlog.processors.StackInfoRenderer(), structlog.processors.format_exc_info, structlog.processors.JSONRenderer() if LOGGING_JSON else structlog.processors.KeyValueRenderer(key_order=['event']), ], logger_factory=structlog.stdlib.LoggerFactory(), wrapper_class=structlog.stdlib.BoundLogger, cache_logger_on_first_use=True, ) epicbox.configure(dict(EPICBOX_BASE_PROFILES, **EPICBOX_PROFILES), base_workdir=EPICBOX_BASE_WORKDIR, docker_url=EPICBOX_DOCKER_URL) configure_jail_code(sys.modules[__name__])
def __init__(self): epicbox.configure( profiles=[epicbox.Profile('python', self.DOCKER_IMAGE)])
def grade_epicbox( compiler: str, prepared_files: dict, tests: list, flags: str, docker_limits: dict, stop_if_fails: bool, memcheck: bool, ) -> list: """ Running grading script in a separate Docker container. https://github.com/StepicOrg/epicbox :param submission: Student submission received from message broker. :param script_name: Name of the grading script. :param prepared_files: List of files and their paths. :param docker_profile: Epicbox profile. :param docker_limits: Docker container limits. :return: Results of grading. """ logger: Logger = get_logger("process_answer") PROFILES = { 'test_code': { 'docker_image': 'test', 'user': '******', 'read_only': False, 'network_disabled': True, } } epicbox.configure(profiles=PROFILES) with epicbox.working_directory() as wd: comp = compile_code(compiler, flags, prepared_files, wd) if comp['exit_code'] != 0: return [{'status': 'CE', 'log': comp['stderr'].decode()}] test_results = [] for test in tests: test_case = epicbox.run('test_code', './main', stdin=test['input'], limits=docker_limits, workdir=wd) test_case['stdout'] = test_case['stdout'].decode() test_case['stderr'] = test_case['stderr'].decode() if test_case['timeout']: result = {'status': 'TL', 'test_name': test['test_name'], 'input': test['input'], \ 'correct_output': test['output'], 'answer': test_case} elif test_case['oom_killed']: result = {'status': 'ML', 'test_name': test['test_name'], 'input': test['input'], \ 'correct_output': test['output'], 'answer': test_case} elif test_case['stdout'] != test['output']: result = {'status': 'WA', 'test_name': test['test_name'], 'input': test['input'], \ 'correct_output': test['output'], 'answer': test_case} else: result = {'status': 'OK', 'test_name': test['test_name'], 'input': test['input'], \ 'correct_output': test['output'], 'answer': test_case} if stop_if_fails == True and result['status'] != 'OK': test_results.append(result) break if memcheck == True and result['status'] == 'OK': memory_check = check_valgrind(test_input, limits, wd) if memory_check['exitcode'] != 0: result['memcheck'] = { 'memcheck': 'ERROR', 'log': memory_check['stderr'].decode() } else: result['memcheck'] = {'memcheck': 'OK'} test_results.append(result) logger.debug("Result: %s", result) return test_results
from flask import Flask, render_template, request, session import random, epicbox, os # docker pull epicbox.configure(profiles=[epicbox.Profile('python', 'python:3.9.6-alpine')]) app = Flask(__name__) app.secret_key = os.urandom(16) flag = open('flag.txt').read() @app.route('/') def yeet(): return render_template('yeet.html') @app.route('/yeet') def yeetyeet(): return render_template('yeetyeet.html') @app.route('/yeetyeet', methods=['POST']) def yeetyeetyeet(): if 'run' in session and session['run']: return { 'error': True, 'msg': 'You already have code running, please wait for it to finish.' } session['run'] = True
#!/usr/bin/env python3 import epicbox epicbox.configure( profiles=[ epicbox.Profile('base', 'stepic/epicbox-base'), epicbox.Profile('python', 'stepic/epicbox-python', network_disabled=False), ], selinux_enforced=False, ) files = [{'name': 'main.py', 'content': b'print(42)\n'}] r = epicbox.run('python', 'python3 main.py', files=files, limits={'cputime': 1}) print(r)
import epicbox import hashlib from random import randint from sys import stderr epicbox.configure(profiles=[ #epicbox.Profile('python', 'python:3.6.5-alpine') epicbox.Profile('python', 'hortune/python3.6-alpine') ]) q_num = 0 def is_valid(digest, diff): bits = ''.join(bin(i)[2:].zfill(8) for i in digest) return bits[:diff] == '0' * diff def proofofwork(): hardness = 23 prefix = hex( randint(1000000000000000000000000000000000000, 123123123213123000000123213**3))[-18:-2] print(f'prefix = "{prefix}"') print(f'sha256(prefix + answer) has {hardness} leading zeros. (In binary)') print("input:") inp = input().strip() s = prefix + inp assert is_valid(hashlib.sha256(s.encode()).digest(), hardness)
def grade_epicbox( submission: dict, script_name: str, prepared_files: list, docker_profile: dict, docker_limits: dict, ) -> dict: """ Running grading script in a separate Docker container. https://github.com/StepicOrg/epicbox :param submission: Student submission received from message broker. :param script_name: Name of the grading script. :param prepared_files: List of files and their paths. :param docker_profile: Epicbox profile. :param docker_limits: Docker container limits. :return: Results of grading. """ logger: Logger = get_logger("process_answer") epicbox.configure(profiles=[ epicbox.Profile( name="python", docker_image=docker_profile["docker_image"], user=docker_profile["user"], read_only=docker_profile["read_only"], network_disabled=docker_profile["network_disabled"], ) ]) # Get all files used during grading # Content field should be bytes files: list = [] # Grading script with Path(PATH_GRADER_SCRIPTS_DIRECTORY / script_name / "grade.py").open("rb") as f: files.append({"name": "grade.py", "content": f.read()}) # Required files for file in prepared_files: with Path(file["path"]).open("rb") as f: files.append({"name": file["name"], "content": f.read()}) # Student submission files.append({ "name": "student_response.txt", "content": submission_get_response(submission).encode(), }) # Script parameters files.append({ "name": "script_parameters.json", "content": submission["xqueue_body"]["grader_payload"].encode(), }) result: dict = epicbox.run("python", "python3 grade.py", files=files, limits=docker_limits) logger.debug("Result: %s", result) grade: dict = {"correct": False, "score": 0, "msg": ""} # Handling result if result["timeout"]: grade["msg"] = "Проверка заняла слишком много времени." elif result["oom_killed"]: grade["msg"] = "Проверка заняла слишком много памяти." else: try: try: grade["score"] = int(result["stdout"].decode().split("\n")[-2]) except ValueError: grade["score"] = float( result["stdout"].decode().split("\n")[-2]) grade["msg"] = result["stderr"].decode() # .split("\n")[-2] + "\n" grade["correct"] = bool(grade["score"]) except ValueError: raise InvalidGraderScriptException( "Grading script returned invalid results: %s", result) return grade