Repository: cobbler/cobbler

Issue:
Refactoring to dynamic folder creation broke multiple functionallities
### Describe the bug

Merging #3230 before GH Actions finished led to a broken Cobbler that is unable to start and unable to be packaged.

### Steps to reproduce

Try `pytest` on [9d35aa2](https://github.com/cobbler/cobbler/commit/9d35aa29ab3ee19598dc16d9c1e8c70eac947d44)

### Expected behavior

Testsuite and packaging works

### Cobbler version

````paste below
````

### Operating system

openSUSE, Debian, Fedora, ...

### Cobbler log

````paste below
````

### Screenshots

None

### Additional information

None



Discussion:

Resolving patch:
diff --git a/cobbler/utils/filesystem_helpers.py b/cobbler/utils/filesystem_helpers.py
--- a/cobbler/utils/filesystem_helpers.py
+++ b/cobbler/utils/filesystem_helpers.py
@@ -119,7 +119,7 @@ def cachefile(src: str, dst: str):
         copyfile(src, str(cachefile_obj))
 
     logger.debug("trying cachelink %s -> %s -> %s", src, cachefile_obj, dst)
-    cachefile_obj.hardlink_to(dst)
+    os.link(cachefile_obj, dst)
 
 
 def linkfile(api, src: str, dst: str, symlink_ok: bool = False, cache: bool = True):
@@ -155,7 +155,7 @@ def linkfile(api, src: str, dst: str, symlink_ok: bool = False, cache: bool = Tr
         # we can try a hardlink if the destination isn't to NFS or Samba this will help save space and sync time.
         try:
             logger.info("trying hardlink %s -> %s", src, dst)
-            src_obj.hardlink_to(dst_obj)
+            os.link(src, dst)
             return
         except (IOError, OSError):
             # hardlink across devices, or link already exists we'll just symlink it if we can or otherwise copy it
@@ -165,7 +165,7 @@ def linkfile(api, src: str, dst: str, symlink_ok: bool = False, cache: bool = Tr
         # we can symlink anywhere except for /tftpboot because that is run chroot, so if we can symlink now, try it.
         try:
             logger.info("trying symlink %s -> %s", src, dst)
-            src_obj.symlink_to(dst_obj)
+            dst_obj.symlink_to(src_obj)
             return
         except (IOError, OSError):
             pass


Test patch:
diff --git a/tests/utils/filesystem_helpers_test.py b/tests/utils/filesystem_helpers_test.py
--- a/tests/utils/filesystem_helpers_test.py
+++ b/tests/utils/filesystem_helpers_test.py
@@ -65,7 +65,7 @@ def test_linkfile(cobbler_api):
     test_destination = ""
 
     # Act
-    filesystem_helpers.linkfile(test_source, test_destination, api=cobbler_api)
+    filesystem_helpers.linkfile(cobbler_api, test_source, test_destination)
 
     # Assert
     assert False
@@ -233,18 +233,19 @@ def test_create_web_dirs(mocker, cobbler_api):
 def test_create_tftpboot_dirs(mocker, cobbler_api):
     # Arrange
     settings_mock = mocker.MagicMock()
-    settings_mock.webdir = "/my/custom/webdir"
+    settings_mock.tftpboot_location = "/srv/tftpboot"
     mocker.patch.object(cobbler_api, "settings", return_value=settings_mock)
 
     mock_mkdir = mocker.patch("cobbler.utils.filesystem_helpers.mkdir")
-    mock_os_symlink = mocker.patch("pathlib.Path.symlink_to")
+    mock_path_symlink_to = mocker.patch("pathlib.Path.symlink_to")
+    mocker.patch("pathlib.Path.exists", return_value=False)
 
     # Act
     filesystem_helpers.create_tftpboot_dirs(cobbler_api)
 
     # Assert
     assert mock_mkdir.call_count == 12
-    assert mock_os_symlink.call_count == 3
+    assert mock_path_symlink_to.call_count == 3
 
 
 def test_create_trigger_dirs(mocker):