def mission_git_getter(url, slug): # TODO: checkout into mission solder # compile it # build docker # prepare cli interface folder = Folder(slug) destination_path = folder.mission_folder() logging.info("Getting a new mission through the git...") logging.info("from %s to %s", url, destination_path) if os.path.exists(destination_path): answer = raw_input("Folder {} exists already." " Do you want to overwite it? [y]/n :".format(destination_path)) if answer is "" or answer.lower().startswith("y"): shutil.rmtree(destination_path) else: return re_ret = re.search(RE_REPO_BRANCH, url) if re_ret: checkout_url, branch = re_ret.groups() else: checkout_url = url branch = "master" logging.debug("URL info: checkioout url:%s branch:%s", url, branch) try: git.Repo.clone_from(checkout_url, destination_path, branch=branch) except git.GitCommandError as e: raise Exception(u"{}, {}".format(e or "", e.stderr)) folder.mission_config_write({"type": "git", "url": url}) print("Prepare mission {} from {}".format(slug, url))
def use(parser): mission_slug = sys.argv[2] folder = Folder(mission_slug) os.system('cd {mission_path}; git {command}'.format( mission_path=folder.mission_folder(), command=' '.join(sys.argv[3:]) ))
def mission_git_getter(url, slug): # TODO: checkout into mission solder # compile it # build docker # prepare cli interface folder = Folder(slug) destination_path = folder.mission_folder() logging.info('Getting a new mission through the git...') logging.info('from %s to %s', url, destination_path) if os.path.exists(destination_path): answer = raw_input( 'Folder {} exists already.' ' Do you want to overwite it? [y]/n :'.format(destination_path)) if answer is '' or answer.lower().startswith('y'): shutil.rmtree(destination_path) else: return re_ret = re.search(RE_REPO_BRANCH, url) if re_ret: checkout_url, branch = re_ret.groups() else: checkout_url = url branch = 'master' logging.debug('URL info: checkioout url:%s branch:%s', url, branch) try: git.Repo.clone_from(checkout_url, destination_path, branch=branch) except git.GitCommandError as e: raise Exception(u"{}, {}".format(e or '', e.stderr)) folder.mission_config_write({'type': 'git', 'url': url}) print('Prepare mission {} from {}'.format(slug, url))
def write_solution(slug, interpreter, solution_path): logging.info("Write a solution into %s for %s %s", solution_path, slug, interpreter) folder = Folder(slug) mission_config = folder.mission_config() comment_prefix = settings.INTERPRETERS[interpreter]['inline_comment'] fh = open(solution_path, 'w') fh.write(INITIAL_LINE + '\n') fh.write(comment_prefix + LABEL_START_SYS_INFO + '\n') str_config = yaml.dump({ 'mission': slug, 'source': mission_config['source'], 'interpreter': interpreter }, default_flow_style=False) for line in str_config.strip().split('\n'): fh.write(comment_prefix + line + '\n') fh.write(comment_prefix + LABEL_END_SYS_INFO + '\n') fh.write('\n') for file_name in settings.INIT_DESCRIPTION: for line in folder.compiled_info_file_content(file_name + '.md').split('\n'): if line.strip(): fh.write(comment_prefix + line + '\n') else: # To avoid syntax warning 'trailing whitespace' fh.write(comment_prefix.strip() + '\n') fh.write(comment_prefix + LABEL_END_INFO + '\n\n') fh.write(folder.initial_code(interpreter)) fh.close() st = os.stat(solution_path) os.chmod(solution_path, st.st_mode | stat.S_IEXEC)
def make_mission_from_template(mission, template, force_remove=False): template_full_path = None for template_folder in settings.TEMPLATES_FOLDERS: template_full_path = os.path.join(template_folder, template) if os.path.exists(template_full_path): break else: template_full_path = None if template_full_path is None: raise TemplateWasntFound(template, settings.TEMPLATES_FOLDERS) folder = Folder(mission) mission_folder = folder.mission_folder() if os.path.exists(mission_folder): if force_remove: shutil.rmtree(mission_folder) else: raise MissionFolderExistsAlready(mission_folder) os.mkdir(mission_folder) from distutils.dir_util import copy_tree copy_tree(os.path.join(template_full_path, 'source'), mission_folder) GG = {} exec(open(os.path.join(template_full_path, 'run.py')).read()) in GG GG['run'](mission) folder.mission_config_write({'type': 'local', 'url': mission_folder})
def make_mission_from_template(mission, template, force_remove=False): template_full_path = None for template_folder in settings.TEMPLATES_FOLDERS: template_full_path = os.path.join(template_folder, template) if os.path.exists(template_full_path): break else: template_full_path = None if template_full_path is None: raise TemplateWasntFound(template, settings.TEMPLATES_FOLDERS) folder = Folder(mission) mission_folder = folder.mission_folder() if os.path.exists(mission_folder): if force_remove: shutil.rmtree(mission_folder) else: raise MissionFolderExistsAlready(mission_folder) os.mkdir(mission_folder) from distutils.dir_util import copy_tree copy_tree(os.path.join(template_full_path, 'source'), mission_folder) GG = {} exec(open(os.path.join(template_full_path, 'run.py')).read(), GG) GG['run'](mission) folder.mission_config_write({ 'type': 'local', 'url': mission_folder })
def run(slug): folder = Folder(slug) print('Congratulation!!!') print('You have new mission created with slug {}'.format(slug)) print('In the folder {} you find all files that explains what this mission about' .format(os.path.join(folder.mission_folder(), 'info'))) print('Change initial user code in folder {}' .format(os.path.join(folder.mission_folder(), 'initial')))
def recompile_mission(slug): folder = Folder(slug) compiled_path = folder.compiled_folder_path() logging.info("Relink folder to %s", compiled_path) if os.path.exists(compiled_path): shutil.rmtree(compiled_path) mission_source = MissionFilesCompiler(compiled_path) mission_source.compile(source_path=folder.mission_folder(), use_link=True)
def recompile_mission(slug): folder = Folder(slug) compiled_path = folder.compiled_folder_path() logging.info("Relink folder to %s", compiled_path) if os.path.exists(compiled_path): shutil.rmtree(compiled_path) mission_source = MissionFilesCompiler(compiled_path) mission_source.compile(source_path=folder.mission_folder(), use_link=True)
def run(slug): folder = Folder(slug) print('Congratulation!!!') print('You have new mission created with slug {}'.format(slug)) print( 'In the folder {} you find all files that explains what this mission about' .format(os.path.join(folder.mission_folder(), 'info'))) print('Change initial user code in folder {}'.format( os.path.join(folder.mission_folder(), 'initial')))
def rebuild_mission(slug): folder = Folder(slug) docker = DockerClient() verification_folder_path = folder.container_verification_folder_path() logging.info("Build docker image %s from %s", folder.image_name(), verification_folder_path) if os.path.exists(verification_folder_path): shutil.rmtree(verification_folder_path) copy_tree(folder.verification_folder_path(), verification_folder_path) docker.build(name_image=folder.image_name(), path=verification_folder_path)
def run(options): file_options = get_file_options(options.filename) folder = Folder(file_options['mission']) if not folder.exists(): # TODO: try to get mission raise ValueError('Mission doesn\'t exists') if options.check: command = 'check' else: command = 'run' execute_referee(command, file_options['mission'], file_options['interpreter'], without_container=options.without_container, interface_child=options.interface_child, interface_only=options.interface_only, referee_only=options.referee_only)
def rebuild_native(slug): folder = Folder(slug) logging.info('Building virtualenv in %s', folder.native_env_folder_path()) if os.path.exists(folder.native_env_folder_path()): shutil.rmtree(folder.native_env_folder_path()) logging_sys("virtualenv --system-site-packages -p python3 " + folder.native_env_folder_path()) logging_sys("{pip3} install -r {requirements}".format( pip3=folder.native_env_bin('pip3'), requirements=folder.referee_requirements())) logging_sys("{pip3} install -r {requirements}".format( pip3=folder.native_env_bin('pip3'), requirements=folder.interface_cli_requirements()))
def run(options): file_options = get_file_options(options.filename) folder = Folder(file_options['mission']) if not folder.exists(): # TODO: try to get mission raise ValueError('Mission doesn\'t exists') if options.check: command = 'check' else: command = 'run' execute_referee(command, file_options['mission'], file_options['interpreter'], without_container=options.without_container, interface_child=options.interface_child, interface_only=options.interface_only, referee_only=options.referee_only)
def start_docker(slug): if is_linux(): local_ip = settings.DOCKER_LINUX_IP else: local_ip = socket.gethostbyname(socket.gethostname()) command = "{} {} 1 2 {}".format(local_ip, settings.CONSOLE_SERVER_PORT, str(logging.root.level)) docker_client = DockerClient() folder = Folder(slug) copy_tree(folder.verification_folder_path(), folder.container_verification_folder_path()) docker_container = docker_client.run(slug, command, volumes={ '/opt/mission/src': folder.compiled_referee_folder_path(), '/opt/mission/envs': folder.compiled_envs_folder_path() }) for line in docker_container.logs(stream=True, logs=True): try: logging.info(line) except Exception as e: logging.error(e, exc_info=True) pass
def init_home_file(slug, interpreter): folder = Folder(slug) if not os.path.exists(folder.init_file_path(interpreter)): available_list = folder.init_available_list() if not available_list: logging.warning('Do not support any language. Initials is empty.') return default = available_list[0] str_propose = '[{}]/{}'.format(default, '/'.join(available_list[1:])) answer = raw_input(('Mission "{}" doesn\'t support {}.' + ' Please choose one out of available {}:').format( slug, interpreter, str_propose)) answer = answer.strip() if not answer: answer = default _, interpreter = set_mi(interpreter=answer, do_raise=False) return init_home_file(slug, interpreter) write_solution(slug, interpreter, folder.solution_path())
def mission_git_init(mission, original_url): folder = Folder(mission) mission_folder = folder.mission_folder() logging.info("Init git repository for folder %s", mission_folder) repo = git.Repo.init(mission_folder) for root, dirs, files in os.walk(mission_folder): if root.endswith(".git") or "/.git/" in root: continue for file_name in files: abs_file_name = os.path.join(root, file_name) logging.debug("Add file to local git repository %s", abs_file_name) repo.index.add([abs_file_name]) repo.index.commit("initial commit") origin = repo.create_remote("origin", original_url) origin.push(repo.refs) origin.fetch() repo.create_head("master", origin.refs.master).set_tracking_branch(origin.refs.master) folder.mission_config_write({"type": "git", "url": original_url})
def init_home_file(slug, interpreter): folder = Folder(slug) if not os.path.exists(folder.init_file_path(interpreter)): available_list = folder.init_available_list() if not available_list: logging.warning('Do not support any language. Initials is empty.') return default = available_list[0] str_propose = '[{}]/{}'.format(default, '/'.join(available_list[1:])) answer = raw_input(('Mission "{}" doesn\'t support {}.' + ' Please choose one out of available {}:').format(slug, interpreter, str_propose)) answer = answer.strip() if not answer: answer = default _, interpreter = set_mi(interpreter=answer, do_raise=False) return init_home_file(slug, interpreter) write_solution(slug, interpreter, folder.solution_path())
def mission_git_init(mission, original_url): folder = Folder(mission) mission_folder = folder.mission_folder() logging.info('Init git repository for folder %s', mission_folder) repo = git.Repo.init(mission_folder) for root, dirs, files in os.walk(mission_folder): if root.endswith('.git') or '/.git/' in root: continue for file_name in files: abs_file_name = os.path.join(root, file_name) logging.debug('Add file to local git repository %s', abs_file_name) repo.index.add([abs_file_name]) repo.index.commit("initial commit") origin = repo.create_remote('origin', original_url) origin.push(repo.refs) origin.fetch() repo.create_head('master', origin.refs.master).set_tracking_branch( origin.refs.master) folder.mission_config_write({'type': 'git', 'url': original_url})
def start_docker(slug): if is_linux(): local_ip = settings.DOCKER_LINUX_IP else: local_ip = socket.gethostbyname(socket.gethostname()) command = "{} {} 1 2 {}".format(local_ip, settings.CONSOLE_SERVER_PORT, str(logging.root.level)) docker_client = DockerClient() folder = Folder(slug) copy_tree(folder.verification_folder_path(), folder.container_verification_folder_path()) docker_container = docker_client.run( slug, command, volumes={ '/opt/mission/src': folder.compiled_referee_folder_path(), '/opt/mission/envs': folder.compiled_envs_folder_path() }) for line in docker_container.logs(stream=True, logs=True): try: logging.info(line) except Exception as e: logging.error(e, exc_info=True) pass
def rebuild_native(slug): folder = Folder(slug) logging.info('Building virtualenv in %s', folder.native_env_folder_path()) if os.path.exists(folder.native_env_folder_path()): shutil.rmtree(folder.native_env_folder_path()) logging_sys("virtualenv --system-site-packages -p python3 " + folder.native_env_folder_path()) logging_sys("{pip3} install -r {requirements}".format( pip3=folder.native_env_bin('pip3'), requirements=folder.referee_requirements() )) logging_sys("{pip3} install -r {requirements}".format( pip3=folder.native_env_bin('pip3'), requirements=folder.interface_cli_requirements() ))
def mission_git_init(mission, original_url): folder = Folder(mission) mission_folder = folder.mission_folder() logging.info('Init git repository for folder %s', mission_folder) repo = git.Repo.init(mission_folder) for root, dirs, files in os.walk(mission_folder): if root.endswith('.git') or '/.git/' in root: continue for file_name in files: abs_file_name = os.path.join(root, file_name) logging.debug('Add file to local git repository %s', abs_file_name) repo.index.add([abs_file_name]) repo.index.commit("initial commit") origin = repo.create_remote('origin', original_url) origin.push(repo.refs) origin.fetch() repo.create_head('master', origin.refs.master).set_tracking_branch(origin.refs.master) folder.mission_config_write({ 'type': 'git', 'url': original_url })
def write_solution(slug, interpreter, solution_path): logging.info("Write a solution into %s for %s %s", solution_path, slug, interpreter) folder = Folder(slug) mission_config = folder.mission_config() comment_prefix = settings.INTERPRETERS[interpreter]['inline_comment'] fh = open(solution_path, 'w') fh.write(INITIAL_LINE + '\n') fh.write(comment_prefix + LABEL_START_SYS_INFO + '\n') str_config = yaml.dump( { 'mission': slug, 'source': mission_config['source'], 'interpreter': interpreter }, default_flow_style=False) for line in str_config.strip().split('\n'): fh.write(comment_prefix + line + '\n') fh.write(comment_prefix + LABEL_END_SYS_INFO + '\n') fh.write('\n') for file_name in settings.INIT_DESCRIPTION: for line in folder.compiled_info_file_content(file_name + '.md').split('\n'): if line.strip(): fh.write(comment_prefix + line + '\n') else: # To avoid syntax warning 'trailing whitespace' fh.write(comment_prefix.strip() + '\n') fh.write(comment_prefix + LABEL_END_INFO + '\n\n') fh.write(folder.initial_code(interpreter)) fh.close() st = os.stat(solution_path) os.chmod(solution_path, st.st_mode | stat.S_IEXEC)
def execute_referee(command, slug, interpreter, without_container=False, interface_child=False, referee_only=False, interface_only=False): # TODO: killing server after words def start_interface(tmp_file_name=None): return start_server(slug, folder.interface_cli_main(), command, folder.solution_path(), folder.native_env_bin('python3'), interpreter, tmp_file_name) def start_container(): return start_docker(slug) def start_local(): return start_native(folder.referee_folder_path(), folder.native_env_bin('python3')) folder = Folder(slug) if interface_only: return start_interface() if referee_only: if without_container: return start_local() else: return start_container (_, tmp_file_name) = tempfile.mkstemp() pid_child = os.fork() start_interface_first = bool(pid_child) if interface_child: start_interface_first = not start_interface_first if start_interface_first: return start_interface(tmp_file_name) else: while os.path.exists(tmp_file_name): time.sleep(1) # give more time to start interface first if without_container: return start_local() else: return start_container()
def rebuild_mission(slug): folder = Folder(slug) docker = DockerClient() verification_folder_path = folder.container_verification_folder_path() logging.info("Build docker image %s from %s", folder.image_name(), verification_folder_path) if os.path.exists(verification_folder_path): shutil.rmtree(verification_folder_path) copy_tree(folder.verification_folder_path(), verification_folder_path) docker.build(name_image=folder.image_name(), path=verification_folder_path)
def use(parser): mission_slug = sys.argv[2] folder = Folder(mission_slug) os.system('cd {mission_path}; git {command}'.format( mission_path=folder.mission_folder(), command=' '.join(sys.argv[3:])))