def test_transmit_permissions(tmp_path, fperm): # breakpoint() pdd = tmp_path / 'transmit_permission_test' pdd.mkdir() old_file_path = pdd / 'ordinary_file.txt' with open(old_file_path, 'w') as f: f.write('hello world') old_file_path.chmod(fperm) # SANITY - set expectations for the file # assert oct(os.stat(old_file_path).st_mode & 0o777) == oct(fperm) assert oct(old_file_path.stat().st_mode & 0o777) == oct(fperm) outgoing_buffer = io.BytesIO() outgoing_buffer.name = 'not_stdout' stream_dir(pdd, outgoing_buffer) dest_dir = tmp_path / 'transmit_permission_dest' outgoing_buffer.seek(0) first_line = outgoing_buffer.readline() size_data = json.loads(first_line.strip()) unstream_dir(outgoing_buffer, size_data['zipfile'], dest_dir) # Assure the new file is the same permissions new_file_path = dest_dir / 'ordinary_file.txt' assert oct(new_file_path.stat().st_mode) == oct( old_file_path.stat().st_mode)
def test_transmit_symlink(tmp_path, symlink_dest, check_content): symlink_dest = Path(symlink_dest) # prepare the input private_data_dir directory to zip pdd = tmp_path / 'symlink_zip_test' pdd.mkdir() # Create some basic shared demo content with open(pdd / 'ordinary_file.txt', 'w') as f: f.write('hello world') ord_dir = pdd / 'ordinary_directory' ord_dir.mkdir() with open(ord_dir / 'dir_file.txt', 'w') as f: f.write('hello world') old_symlink_path = pdd / 'my_link' old_symlink_path.symlink_to(symlink_dest) # SANITY - set expectations for the symlink assert old_symlink_path.is_symlink() assert os.readlink(old_symlink_path) == str(symlink_dest) # zip and stream the data into the in-memory buffer outgoing_buffer outgoing_buffer = io.BytesIO() outgoing_buffer.name = 'not_stdout' stream_dir(pdd, outgoing_buffer) # prepare the destination private_data_dir to transmit to dest_dir = tmp_path / 'symlink_zip_dest' dest_dir.mkdir() # Extract twice so we assure that existing data does not break things for i in range(2): # rewind the buffer and extract into destination private_data_dir outgoing_buffer.seek(0) first_line = outgoing_buffer.readline() size_data = json.loads(first_line.strip()) unstream_dir(outgoing_buffer, size_data['zipfile'], dest_dir) # Assure the new symlink is still the same type of symlink new_symlink_path = dest_dir / 'my_link' assert new_symlink_path.is_symlink() assert os.readlink(new_symlink_path) == str(symlink_dest) for fname in check_content: abs_path = dest_dir / fname assert abs_path.exists( ), f'Expected "{fname}" in target dir to be a file with content.' with open(abs_path, 'r') as f: assert f.read() == 'hello world'
def run(self): while True: try: line = self._input.readline() data = json.loads(line) except (json.decoder.JSONDecodeError, IOError): self.status_handler( { 'status': 'error', 'job_explanation': 'Failed to JSON parse a line from transmit stream.' }, None) self.finished_callback(None) # send eof line return self.status, self.rc if 'kwargs' in data: self.job_kwargs = self.update_paths(data['kwargs']) elif 'zipfile' in data: try: unstream_dir(self._input, data['zipfile'], self.private_data_dir) except Exception: self.status_handler( { 'status': 'error', 'job_explanation': 'Failed to extract private data directory on worker.', 'result_traceback': traceback.format_exc() }, None) self.finished_callback(None) # send eof line return self.status, self.rc elif 'eof' in data: break self.kwargs.update(self.job_kwargs) self.kwargs['quiet'] = True self.kwargs['suppress_ansible_output'] = True self.kwargs['private_data_dir'] = self.private_data_dir self.kwargs['status_handler'] = self.status_handler self.kwargs['event_handler'] = self.event_handler self.kwargs['artifacts_handler'] = self.artifacts_handler self.kwargs['finished_callback'] = self.finished_callback r = ansible_runner.interface.run(**self.kwargs) self.status, self.rc = r.status, r.rc # FIXME: do cleanup on the tempdir return self.status, self.rc
def artifacts_callback(self, artifacts_data): length = artifacts_data['zipfile'] unstream_dir(self._input, length, self.artifact_dir) if self.artifacts_handler is not None: self.artifacts_handler(self.artifact_dir)