def _synchronize_task_dir(self, agent): """ Synchronizes the task directory with the remote agent. Steps are: - Get list of (path, file hash) for the main task directory (p1) - Ask agent for a list of all files in their task directory (p1) - Find differences for each agents (p2) - Create an archive with differences (p2) - Send it to each agent (p2) - Agents updates their directory """ local_td = self._last_content_in_task_directory # As agent only supports task.yaml files as descriptors (and not exotic things like task.rst...), we have to ensure that we convert and send # task.yaml files to it. task_files_to_convert = ["task." + ext for ext in get_available_task_file_managers()] task_files_to_convert.remove("task.yaml") new_local_td = {} generated_yaml_content = {} for file_path, data in local_td.iteritems(): match = re.match(r'^([a-zA-Z0-9_\-]+)/([a-zA-Z0-9_\-]+)/(task.[a-z0-9]+)$', file_path) if match is not None and match.group(3) in task_files_to_convert: try: path_to_file, _ = os.path.split(file_path) courseid, taskid = match.group(1), match.group(2) content = get_task_file_manager(courseid, taskid).read() yaml_content = StringIO(common.custom_yaml.dump(content).encode('utf-8')) new_local_td[os.path.join(path_to_file, "task.yaml")] = (hash_file(yaml_content), 0o777) yaml_content.seek(0) generated_yaml_content[os.path.join(path_to_file, "task.yaml")] = yaml_content except: print "Cannot convert {} to a yaml file for the agent!".format(file_path) new_local_td[file_path] = data else: new_local_td[file_path] = data async_get_file_list = rpyc.async(agent.root.get_task_directory_hashes) async_get_file_list().add_callback(lambda r: self._synchronize_task_dir_p2(agent, new_local_td, generated_yaml_content, r))
def test_hash_file(self): tmp = tempfile.TemporaryFile() tmp.write("some random text") tmp.flush() tmp.seek(0) assert hash_file(tmp) == "07671a038c0eb43723d421693b073c3b"