Repository: cobbler/cobbler

Issue:
cobbler reposync fails with error /var/www/cobbler/repo_mirror/<reponame>/.origin/repodata: File exists: 'Cannot create output directory'
### Describe the bug
cobbler reposync runs successfully for first time but fails after consecutive runs. 
<!--- 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. Create new repo
2. Run # cobbler reposync  < - Successful
3. Run again # cobbler reposync < - Fails with error  "/var/www/cobbler/repo_mirror/<reponame>/.origin/repodata: File exists: 'Cannot create output directory'"

### Expected behavior
cobbler reposync should complete successfully on every run.
<!--- A clear and concise description of what you expected to happen. -->

### Cobbler version

<!--- Paste output from `cobbler version` -->
````
cobbler-3.2.2-4.module_el8+13419+741870f6.noarch
cobbler-web-3.2.2-4.module_el8+13419+741870f6.noarch
# cobbler --version
Cobbler 3.2.2
  source: ?, ?
  build time: Tue Nov 23 03:07:49 2021
````



### Operating system
CentOS Stream release 8
<!--- On which operating system do you use Cobbler? -->

### Cobbler log


<!--- Paste (partial) output from `/var/log/cobbler/cobbler.log` -->
````
2021-12-17T08:57:58 - INFO | reposync; [None]
2021-12-17T08:59:41 - INFO | REMOTE invalid token; user(???)
2021-12-17T08:59:47 - INFO | authenticate; ['cobbler', True]
2021-12-17T08:59:48 - INFO | authenticate; ['cobbler', True]
2021-12-17T08:59:48 - DEBUG | authorize; ['cobbler', 'modify_repo', <cobbler.items.repo.Repo object at 0x7f53fdfb30b8>, None, True]
2021-12-17T08:59:48 - DEBUG | REMOTE cobbler authorization result: True; user(?)
2021-12-17T08:59:48 - INFO | REMOTE get_item(repo,CentOS-7-x86_64-base); user(?)
2021-12-17T08:59:48 - DEBUG | get_item; ['repo', 'CentOS-7-x86_64-base']
2021-12-17T08:59:48 - DEBUG | done with get_item; ['repo', 'CentOS-7-x86_64-base']
2021-12-17T08:59:48 - INFO | REMOTE get_settings; user(?)
2021-12-17T08:59:48 - DEBUG | REMOTE my settings are: {'allow_duplicate_hostnames': False, 'allow_duplicate_ips': False, 'allow_duplicate_macs': False, 'allow_dynamic_settings': False, 'always_write_dhcp_entries': False, 'anamon_enabled': False, 'auth_token_expiration': 3600, 'authn_pam_service': 'login', 'autoinstall_snippets_dir': '/var/lib/cobbler/snippets', 'autoinstall_templates_dir': '/var/lib/cobbler/templates', 'bind_chroot_path': '', 'bind_master': '127.0.0.1', 'boot_loader_conf_template_dir': '/etc/cobbler/boot_loader_conf', 'bootloaders_dir': '/var/lib/cobbler/loaders', 'grubconfig_dir': '/var/lib/cobbler/grub_config', 'build_reporting_enabled': False, 'build_reporting_email': ['root@localhost'], 'build_reporting_ignorelist': [], 'build_reporting_sender': '', 'build_reporting_smtp_server': 'localhost', 'build_reporting_subject': '', 'buildisodir': '/var/cache/cobbler/buildiso', 'cache_enabled': True, 'cheetah_import_whitelist': ['random', 're', 'time', 'netaddr'], 'client_use_https': False, 'client_use_localhost': False, 'cobbler_master': '', 'convert_server_to_ip': False, 'createrepo_flags': '-c cache -s sha', 'default_autoinstall': '/var/lib/cobbler/templates/default.ks', 'default_name_servers': [], 'default_name_servers_search': [], 'default_ownership': ['admin'], 'default_password_crypted': '$1$mF86/UHC$WvcIcX2t6crBz2onWxyac.', 'default_template_type': 'cheetah', 'default_virt_bridge': 'xenbr0', 'default_virt_disk_driver': 'raw', 'default_virt_file_size': 5, 'default_virt_ram': 512, 'default_virt_type': 'xenpv', 'enable_gpxe': False, 'enable_menu': True, 'http_port': 80, 'include': ['/etc/cobbler/settings.d/*.settings'], 'iso_template_dir': '/etc/cobbler/iso', 'jinja2_includedir': '/var/lib/cobbler/jinja2', 'kernel_options': {}, 'ldap_anonymous_bind': True, 'ldap_base_dn': 'DC=example,DC=com', 'ldap_port': 389, 'ldap_search_bind_dn': '', 'ldap_search_passwd': '', 'ldap_search_prefix': 'uid=', 'ldap_server': 'ldap.example.com', 'ldap_tls': True, 'ldap_tls_cacertfile': '', 'ldap_tls_certfile': '', 'ldap_tls_keyfile': '', 'bind_manage_ipmi': True, 'manage_dhcp': False, 'manage_dns': False, 'manage_forward_zones': [], 'manage_reverse_zones': [], 'manage_genders': False, 'manage_rsync': False, 'manage_tftpd': True, 'mgmt_classes': [], 'mgmt_parameters': {'from_cobbler': True}, 'next_server': '127.0.0.1', 'nsupdate_enabled': False, 'nsupdate_log': '/var/log/cobbler/nsupdate.log', 'nsupdate_tsig_algorithm': 'hmac-sha512', 'nsupdate_tsig_key': ['cobbler_update_key.', 'hvnK54HFJXFasHjzjEn09ASIkCOGYSnofRq4ejsiBHz3udVyGiuebFGAswSjKUxNuhmllPrkI0HRSSmM2qvZug=='], 'power_management_default_type': 'ipmilan', 'proxy_url_ext': '', 'proxy_url_int': '', 'puppet_auto_setup': False, 'puppet_parameterized_classes': True, 'puppet_server': '', 'puppet_version': 2, 'puppetca_path': '/usr/bin/puppet', 'pxe_just_once': True, 'nopxe_with_triggers': True, 'redhat_management_permissive': False, 'redhat_management_server': 'xmlrpc.rhn.redhat.com', 'redhat_management_key': '', 'register_new_installs': False, 'remove_old_puppet_certs_automatically': False, 'replicate_repo_rsync_options': '-avzH', 'replicate_rsync_options': '-avzH', 'reposync_flags': '-n --delete', 'reposync_rsync_flags': '-rltDv --copy-unsafe-links', 'restart_dhcp': True, 'restart_dns': True, 'run_install_triggers': True, 'scm_track_enabled': False, 'scm_track_mode': 'git', 'scm_track_author': 'cobbler <cobbler@localhost>', 'scm_push_script': '/bin/true', 'serializer_pretty_json': False, 'server': '172.16.200.168', 'sign_puppet_certs_automatically': False, 'signature_path': '/var/lib/cobbler/distro_signatures.json', 'signature_url': 'https://cobbler.github.io/signatures/3.0.x/latest.json', 'tftpboot_location': '/var/lib/tftpboot', 'virt_auto_boot': True, 'webdir': '/var/www/cobbler', 'webdir_whitelist': ['misc', 'web', 'webui', 'localmirror', 'repo_mirror', 'distro_mirror', 'images', 'links', 'pub', 'repo_profile', 'repo_system', 'svc', 'rendered', '.link_cache'], 'xmlrpc_port': 25151, 'yum_distro_priority': 1, 'yum_post_install_mirror': True, 'yumdownloader_flags': '--resolve'}; user(?)
2021-12-17T08:59:48 - INFO | REMOTE get_autoinstall_templates; user(?)
2021-12-17T08:59:48 - INFO | REMOTE version; user(cobbler)
2021-12-17T09:14:25 - INFO | REMOTE version; user(?)

````

### Screenshots

<!--- If applicable, add screenshots to help explain your problem. -->

### Additional information
## First Run - Successful 
````
running python triggers from /var/lib/cobbler/triggers/task/reposync/pre/*
running shell triggers from /var/lib/cobbler/triggers/task/reposync/pre/*
shell triggers finished successfully
hello, reposync
run, reposync, run!
creating: /var/www/cobbler/repo_mirror/CentOS-7-x86_64-base/config.repo
creating: /var/www/cobbler/repo_mirror/CentOS-7-x86_64-base/.origin/CentOS-7-x86_64-base.repo
running: /usr/bin/dnf reposync -n --delete --config=/var/www/cobbler/repo_mirror/CentOS-7-x86_64-base/.origin/CentOS-7-x86_64-base.repo --repoid=CentOS-7-x86_64-base -p /var/www/cobbler/repo_mirror -a x86_64
received on stdout: CentOS-7-x86_64-base                             39 MB/s |  25 MB     00:00
Last metadata expiration check: 0:00:09 ago on Fri 17 Dec 2021 08:49:27 AM UTC.
(1/4774): ElectricFence-2.2.2-39.el7.x86_64.rpm 2.3 MB/s |  35 kB     00:00
(2/4774): PyGreSQL-4.0-9.el7.x86_64.rpm         3.1 MB/s |  74 kB     00:00
(4770/4774): zsh-html-5.0.2-34.el7_8.2.x86_64.r 5.8 MB/s | 465 kB     00:00
(4771/4774): vsftpd-sysvinit-3.0.2-28.el7.x86_6 395 kB/s |  24 kB     00:00
(4772/4774): zsh-5.0.2-34.el7_8.2.x86_64.rpm     12 MB/s | 2.4 MB     00:00
(4773/4774): vte291-0.52.4-1.el7.x86_64.rpm     2.9 MB/s | 250 kB     00:00
(4774/4774): xerces-c-3.1.1-10.el7_7.x86_64.rpm 6.5 MB/s | 879 kB     00:00

received on stderr:
running: createrepo -g /var/www/cobbler/repo_mirror/CentOS-7-x86_64-base/.origin/repodata/2bdd2671151dd556f3dbfdf62d392c5a1f323d01-c7-x86_64-comps.xml -c cache -s sha /var/www/cobbler/repo_mirror/CentOS-7-x86_64-base
received on stdout: Directory walk started
Directory walk done - 4774 packages
Using 2bdd2671151dd556f3dbfdf62d392c5a1f323d01-c7-x86_64-comps.xml from target repo
Temporary output repo path: /var/www/cobbler/repo_mirror/CentOS-7-x86_64-base/.repodata/
Preparing sqlite DBs
Pool started (with 5 workers)
Pool finished

received on stderr:
running: chown -R root:apache /var/www/cobbler/repo_mirror/CentOS-7-x86_64-base
received on stdout:
received on stderr:
running: chmod -R 755 /var/www/cobbler/repo_mirror/CentOS-7-x86_64-base
received on stdout:
received on stderr:
### TASK COMPLETE ###
running python triggers from /var/lib/cobbler/triggers/task/reposync/post/*
running shell triggers from /var/lib/cobbler/triggers/task/reposync/post/*
shell triggers finished successfully

````

## Second Run - Failed
````
# cat 2021-12-17_085757_reposync.log
running python triggers from /var/lib/cobbler/triggers/task/reposync/pre/*
running shell triggers from /var/lib/cobbler/triggers/task/reposync/pre/*
shell triggers finished successfully
hello, reposync
run, reposync, run!
creating: /var/www/cobbler/repo_mirror/CentOS-7-x86_64-base/config.repo
creating: /var/www/cobbler/repo_mirror/CentOS-7-x86_64-base/.origin/CentOS-7-x86_64-base.repo
running: /usr/bin/dnf reposync -n --delete --config=/var/www/cobbler/repo_mirror/CentOS-7-x86_64-base/.origin/CentOS-7-x86_64-base.repo --repoid=CentOS-7-x86_64-base -p /var/www/cobbler/repo_mirror -a x86_64
received on stdout: CentOS-7-x86_64-base                             57 kB/s | 3.1 kB     00:00
[SKIPPED] ORBit2-2.14.19-13.el7.x86_64.rpm: Already downloaded
[SKIPPED] PyGreSQL-4.0-9.el7.x86_64.rpm: Already downloaded
[SKIPPED] ElectricFence-2.2.2-39.el7.x86_64.rpm: Already downloaded
[SKIPPED] PyPAM-0.5.0-19.el7.x86_64.rpm: Already downloaded
[SKIPPED] GConf2-3.2.6-8.el7.x86_64.rpm: Already downloaded
[SKIPPED] GConf2-devel-3.2.6-8.el7.x86_64.rpm: Already downloaded
...
..
[SKIPPED] xerces-c-3.1.1-10.el7_7.x86_64.rpm: Already downloaded

received on stderr:
Exception occurred: <class 'OSError'>
Exception value: [Errno unknown] Cannot create directory: /var/www/cobbler/repo_mirror/CentOS-7-x86_64-base/.origin/repodata: File exists: 'Cannot create output directory'
Exception Info:
  File "/usr/lib/python3.6/site-packages/cobbler/actions/reposync.py", line 161, in run
    self.sync(repo)

  File "/usr/lib/python3.6/site-packages/cobbler/actions/reposync.py", line 204, in sync
    self.yum_sync(repo)

  File "/usr/lib/python3.6/site-packages/cobbler/actions/reposync.py", line 622, in yum_sync
    h.perform(r)

  File "/usr/lib64/python3.6/site-packages/librepo/__init__.py", line 1595, in perform
    _librepo.Handle.perform(self, result)

reposync failed, tries left: 0
Exception occurred: <class 'cobbler.cexceptions.CX'>
Exception value: 'reposync failed, retry limit reached, aborting'
Exception Info:
  File "/usr/lib/python3.6/site-packages/cobbler/utils.py", line 95, in die
    raise CX(msg)

Exception occurred: <class 'cobbler.cexceptions.CX'>
Exception value: 'reposync failed, retry limit reached, aborting'
Exception Info:
  File "/usr/lib/python3.6/site-packages/cobbler/remote.py", line 98, in run
    rc = self._run(self)

  File "/usr/lib/python3.6/site-packages/cobbler/remote.py", line 326, in runner
    name=None, nofail=nofail, logger=self.logger)

  File "/usr/lib/python3.6/site-packages/cobbler/api.py", line 1375, in reposync
    action_reposync.run(name)

  File "/usr/lib/python3.6/site-packages/cobbler/actions/reposync.py", line 182, in run
    utils.die(self.logger, "reposync failed, retry limit reached, aborting")

  File "/usr/lib/python3.6/site-packages/cobbler/utils.py", line 103, in die
    raise CX(msg)

### TASK FAILED ###
````
<!--- Add any other context about the problem here. -->



Discussion:
@neotheonce Could you confirm with 3.3.3 that this is fixed or if it still is persisting?
It has been fixed. Thank you very much.
When can we expect cobbler-web-3.3 RPM ? 
@neotheonce Thanks for the confirmation that this is fixed. Sadly I have no ETA yet as my private time availability shifts a lot. I will definitely release 3.4.0 with the new CLI and new WebUI.

Resolving patch:
diff --git a/cobbler/actions/reposync.py b/cobbler/actions/reposync.py
--- a/cobbler/actions/reposync.py
+++ b/cobbler/actions/reposync.py
@@ -443,6 +443,9 @@ def rhn_sync(self, repo):
         if repo.arch != "":
             cmd = "%s -a %s" % (cmd, repo.arch)
 
+        if repo.arch == "":
+            cmd = "%s" % (cmd)
+
         # Now regardless of whether we're doing yumdownloader or reposync or whether the repo was http://, ftp://, or
         # rhn://, execute all queued commands here. Any failure at any point stops the operation.
 
@@ -537,7 +540,7 @@ def yum_sync(self, repo):
                     # Counter-intuitive, but we want the newish kernels too
                     cmd = "%s -a i686" % (cmd)
                 else:
-                    cmd = "%s -a %s" % (cmd, repo.arch)
+                    cmd = "%s -a %s -a noarch" % (cmd, repo.arch)
 
         else:
             # Create the output directory if it doesn't exist
@@ -570,12 +573,16 @@ def yum_sync(self, repo):
             proxy = repo.proxy
         (cert, verify) = self.gen_urlgrab_ssl_opts(repo.yumopts)
 
-        # FIXME: These two variables were deleted
-        repodata_path = ""
-        repomd_path = ""
+        repodata_path = os.path.join(temp_path, "repodata")
+        repomd_path = os.path.join(repodata_path, "repomd.xml")
         if os.path.exists(repodata_path) and not os.path.isfile(repomd_path):
             shutil.rmtree(repodata_path, ignore_errors=False, onerror=None)
 
+        repodata_path = os.path.join(temp_path, "repodata")
+        if os.path.exists(repodata_path):
+            self.logger.info("Deleted old repo metadata for %s" % repodata_path)
+            shutil.rmtree(repodata_path, ignore_errors=False, onerror=None)
+
         h = librepo.Handle()
         r = librepo.Result()
         h.setopt(librepo.LRO_REPOTYPE, librepo.LR_YUMREPO)


Test patch: