diff --git a/changelog/63102.fixed.md b/changelog/63102.fixed.md new file mode 100644 index 00000000000..535e1a6c804 --- /dev/null +++ b/changelog/63102.fixed.md @@ -0,0 +1 @@ +file.replace and file.search work properly with /proc files diff --git a/salt/modules/file.py b/salt/modules/file.py index e7514091363..e2d2eabaae0 100644 --- a/salt/modules/file.py +++ b/salt/modules/file.py @@ -2539,7 +2539,7 @@ def replace( r_data = mmap.mmap(r_file.fileno(), 0, access=mmap.ACCESS_READ) except (ValueError, OSError): # size of file in /proc is 0, but contains data - r_data = salt.utils.stringutils.to_bytes("".join(r_file)) + r_data = b"".join(r_file) if search_only: # Just search; bail as early as a match is found if re.search(cpattern, r_data): diff --git a/tests/pytests/unit/modules/file/test_file_block_replace.py b/tests/pytests/unit/modules/file/test_file_block_replace.py index 8a05154f41c..8cc9b818b51 100644 --- a/tests/pytests/unit/modules/file/test_file_block_replace.py +++ b/tests/pytests/unit/modules/file/test_file_block_replace.py @@ -48,6 +48,7 @@ def configure_loader_modules(): "__grains__": grains, "__utils__": { "files.is_binary": MagicMock(return_value=False), + "files.is_text": salt.utils.files.is_text, "files.get_encoding": MagicMock(return_value="utf-8"), "stringutils.get_diff": salt.utils.stringutils.get_diff, }, @@ -546,3 +547,17 @@ def test_unfinished_block_exception(multiline_file): content="foobar", backup=False, ) + + +def test_search_proc_file(): + """ + Test that searching content in a /proc file does not raise a TypeError + and handles bytes correctly. + """ + proc_file_path = "/proc/cpuinfo" + + if not os.path.exists(proc_file_path): + pytest.skip(f"{proc_file_path} not available") + + match_found = filemod.search(proc_file_path, "processor") + assert match_found, "Failed to find 'processor' in /proc/cpuinfo"