Repository: cobbler/cobbler

Issue:
cobbler import fails to identify the apt repo in ubuntu import
### Describe the bug

<!--- A clear and concise description of what the bug is. -->

<!--- HINT: You can paste gist.github.com links for long logs or larger files -->

### Steps to reproduce

1. mount ubuntu iso
2. cobbler import --name ubuntu-server-20_04_2-focal-casper --path /mnt/cobbler-import --arch x86_64 --breed ubuntu                                                                                                                                                                                                              

the import works up until the very end:
```
...
checking for apt repo(s)
adding apt repo for ubuntu-server-20_04_2-focal-casper-casper-x86_64
Exception occurred: <class 'TypeError'>
Exception value: arch needs to be of type enums.RepoArchs
Exception Info:
!!! TASK FAILED !!!
```

### Expected behavior

from cobbler 3.2.2

```
creating new profile: ubuntu-server-20_04_2-focal-casper-casper-x86_64                                                                                         
associating repos                                                                                                                                                                                                                                                                                                             
checking for apt repo(s)                                                                                                                                       
adding apt repo for ubuntu-server-20_04_2-focal-casper-casper-x86_64                                                                                                                                                                                                                                                          
Added repos for ubuntu-server-20_04_2-focal-casper-casper-x86_64    
*** TASK COMPLETE ***                                                              
```
<!--- A clear and concise description of what you expected to happen. -->

### Cobbler version

cobbler-3.3.0-2

This is with the patch that fixes cobbler import. 
<!--- Paste output from `cobbler version` -->
````paste below
````

### Operating system

Fedora 33

### Cobbler log

<!--- Paste (partial) output from `/var/log/cobbler/cobbler.log` -->
```
[2021-10-27_154939_import] 2021-10-27T15:50:13 - INFO | associating repos
[2021-10-27_154939_import] 2021-10-27T15:50:13 - INFO | checking for apt repo(s)
[2021-10-27_154939_import] 2021-10-27T15:50:13 - INFO | adding apt repo for ubuntu-server-20_04_2-focal-casper-casper-x86_64
[2021-10-27_154939_import] 2021-10-27T15:50:13 - INFO | Exception occurred: <class 'TypeError'>
[2021-10-27_154939_import] 2021-10-27T15:50:13 - INFO | Exception value: arch needs to be of type enums.RepoArchs
[2021-10-27_154939_import] 2021-10-27T15:50:13 - INFO | Exception Info:
  File "/usr/lib/python3.9/site-packages/cobbler/remote.py", line 99, in run
    rc = self._run(self)

  File "/usr/lib/python3.9/site-packages/cobbler/remote.py", line 305, in runner
    self.remote.api.import_tree(

  File "/usr/lib/python3.9/site-packages/cobbler/api.py", line 1598, in import_tree
    import_module.run(path, mirror_name, network_root, autoinstall_file, arch, breed, os_version)

  File "/usr/lib/python3.9/site-packages/cobbler/modules/managers/import_signatures.py", line 272, in run
    self.repo_finder(distros_added)

  File "/usr/lib/python3.9/site-packages/cobbler/modules/managers/import_signatures.py", line 670, in repo_finder
    repo_adder(current_distro_added)

  File "/usr/lib/python3.9/site-packages/cobbler/modules/managers/import_signatures.py", line 817, in apt_repo_adder
    repo.arch = distribution.arch

  File "/usr/lib/python3.9/site-packages/cobbler/items/repo.py", line 428, in arch
    raise TypeError("arch needs to be of type enums.RepoArchs")

[2021-10-27_154939_import] 2021-10-27T15:50:13 - ERROR | ### TASK FAILED ###
```

### Additional information

<!--- Add any other context about the problem here. -->



Discussion:
I'm seeing this too when trying to import Ubuntu 20.04 on v3.3.0
Okay the error occurs because `distribution.arch` is of `Arch` enum type. This case is not handled on the setter for `repo.arch` sadly so far.

Three options to fix:

1. Use `distribution.arch.value` and let the `str` conversion handle it.
    --> The easiest but most error prone.
2. Create an additional branch to handle the conversion from `Arch` to `RepoArch` type.
    --> Appears to be the most reasonable choice as we then don't have to manually append a `.value` to every case like this.
3. Check if we need the `RepoArch` type at all.
    --> Yes we need it because `none` and `src` are not valid architectures for a machine.
I will use this occasion to also introduce a general conversion from `str` to the enum type. Existing behavior should be untouched as the code so far is a lot of copy & pasta.
Yes I noticed this last night.  Do you envision 2 to be something like:
```
        if isinstance(arch, enums.Archs):
            try:
                arch = enums.RepoArchs[arch.name.upper()]
            except KeyError as error:
                raise ValueError("arch choices include: %s" % list(map(str, enums.RepoArchs))) from error
```
If so, I'm happy to create a PR on this basis.  Ubuntu 20.04 imports fine with this change

Resolving patch:
diff --git a/cobbler/items/repo.py b/cobbler/items/repo.py
--- a/cobbler/items/repo.py
+++ b/cobbler/items/repo.py
@@ -423,7 +423,13 @@ def arch(self, arch: Union[str, enums.RepoArchs]):
                 arch = enums.RepoArchs[arch.upper()]
             except KeyError as error:
                 raise ValueError("arch choices include: %s" % list(map(str, enums.RepoArchs))) from error
-        # Now the arch MUST be of the type of enums.
+        # Convert an arch which came in as an enums.Archs
+        if isinstance(arch, enums.Archs):
+            try:
+                arch = enums.RepoArchs[arch.name.upper()]
+            except KeyError as error:
+                raise ValueError("arch choices include: %s" % list(map(str, enums.RepoArchs))) from error
+        # Now the arch MUST be of the type of enums.RepoArchs
         if not isinstance(arch, enums.RepoArchs):
             raise TypeError("arch needs to be of type enums.RepoArchs")
         self._arch = arch


Test patch:
diff --git a/tests/items/repo_test.py b/tests/items/repo_test.py
--- a/tests/items/repo_test.py
+++ b/tests/items/repo_test.py
@@ -1,7 +1,12 @@
 from cobbler import enums
 from cobbler.api import CobblerAPI
 from cobbler.items.repo import Repo
+import pytest
+from contextlib import contextmanager
 
+@contextmanager
+def does_not_raise():
+    yield
 
 def test_object_creation():
     # Arrange
@@ -162,18 +167,27 @@ def test_os_version():
     assert testrepo.breed == enums.RepoBreeds.YUM
     assert testrepo.os_version == "rhel4"
 
-
-def test_arch():
+@pytest.mark.parametrize("value,expected_exception", [
+    ("x86_64", does_not_raise()),
+    (enums.RepoArchs.X86_64, does_not_raise()),
+    (enums.Archs.X86_64, pytest.raises(AssertionError)),
+    (False, pytest.raises(TypeError)),
+    ("", pytest.raises(ValueError))
+])
+def test_arch(value, expected_exception):
     # Arrange
     test_api = CobblerAPI()
     testrepo = Repo(test_api)
 
     # Act
-    testrepo.arch = "x86_64"
+    with expected_exception:
+        testrepo.arch = value
 
     # Assert
-    assert testrepo.arch == enums.RepoArchs.X86_64
-
+        if isinstance(value, str):
+            assert testrepo.arch.value == value
+        else:
+            assert testrepo.arch == value
 
 def test_mirror_locally():
     # Arrange