Repository: NVIDIA/hpc-container-maker

Issue:
yum errors with same repo twice
When installing both nsys and nsight-compute in a centos container, it issues the following command: 

```
RUN rpm --import https://developer.download.nvidia.com/devtools/repos/rhel7/x86_64/nvidia.pub && \
    yum install -y yum-utils && \
    yum-config-manager --add-repo https://developer.download.nvidia.com/devtools/repos/rhel7/x86_64 && \
    yum install -y \
        nsight-systems-cli-2021.1.1 && \
    rm -rf /var/cache/yum/*
# NVIDIA Nsight Compute 2020.2.1
RUN rpm --import https://developer.download.nvidia.com/devtools/repos/rhel7/x86_64/nvidia.pub && \
    yum install -y yum-utils && \
    yum-config-manager --add-repo https://developer.download.nvidia.com/devtools/repos/rhel7/x86_64 && \
    yum install -y \
        nsight-compute-2020.2.1 && \
    rm -rf /var/cache/yum/*
```

This errors out because yum-config-manager does not allow the same repo to be added twice:
```
adding repo from: https://developer.download.nvidia.com/devtools/repos/rhel7/x86_64
Cannot add repo from https://developer.download.nvidia.com/devtools/repos/rhel7/x86_64 as is a duplicate of an existing repo
```

Discussion:

Patch:
diff --git a/docs/building_blocks.md b/docs/building_blocks.md
index 8c492de..aac8f1c 100644
--- a/docs/building_blocks.md
+++ b/docs/building_blocks.md
@@ -3623,6 +3623,11 @@ packages are extracted they are deleted. This parameter is ignored
 if `download` is False. If empty, then the downloaded packages are
 not extracted. The default value is an empty string.
 
+- __force_add_repo__: Boolean flag to specify whether adding a
+repository should be considered successful no matter the actual
+result.  This parameter is only valid for yum repositories.  The
+default value is False.
+
 - __ospackages__: A list of packages to install.  The list is used for
 both Ubuntu and RHEL-based Linux distributions, therefore only
 packages with the consistent names across Linux distributions
@@ -4657,6 +4662,10 @@ packages are extracted they are deleted. This parameter is ignored
 if `download` is False. If empty, then the downloaded packages are
 not extracted. The default value is an empty string.
 
+- __force_add_repo__: Boolean flag to specify whether adding a
+repository should be considered successful no matter the actual
+result.  The default value is False.
+
 - __keys__: A list of GPG keys to import.  The default is an empty list.
 
 - __ospackages__: A list of packages to install.  The default is an
diff --git a/hpccm/building_blocks/nsight_compute.py b/hpccm/building_blocks/nsight_compute.py
index 5bff9e7..33265a1 100644
--- a/hpccm/building_blocks/nsight_compute.py
+++ b/hpccm/building_blocks/nsight_compute.py
@@ -172,6 +172,8 @@ class nsight_compute(bb_base):
         self += packages(
             apt_keys=['https://developer.download.nvidia.com/devtools/repos/{0}/{1}/nvidia.pub'.format(self.__distro_label, self.__arch_label)],
             apt_repositories=['deb https://developer.download.nvidia.com/devtools/repos/{0}/{1}/ /'.format(self.__distro_label, self.__arch_label)],
+            # https://github.com/NVIDIA/hpc-container-maker/issues/367
+            force_add_repo=True,
             ospackages=['nsight-compute-{}'.format(self.__version)],
             yum_keys=['https://developer.download.nvidia.com/devtools/repos/{0}/{1}/nvidia.pub'.format(self.__distro_label, self.__arch_label)],
             yum_repositories=['https://developer.download.nvidia.com/devtools/repos/{0}/{1}'.format(self.__distro_label, self.__arch_label)])
diff --git a/hpccm/building_blocks/nsight_systems.py b/hpccm/building_blocks/nsight_systems.py
index 24e1761..4a89e99 100644
--- a/hpccm/building_blocks/nsight_systems.py
+++ b/hpccm/building_blocks/nsight_systems.py
@@ -87,6 +87,8 @@ class nsight_systems(bb_base):
         self += packages(
             apt_keys=['https://developer.download.nvidia.com/devtools/repos/{0}/{1}/nvidia.pub'.format(self.__distro_label, self.__arch_label)],
             apt_repositories=['deb https://developer.download.nvidia.com/devtools/repos/{0}/{1}/ /'.format(self.__distro_label, self.__arch_label)],
+            # https://github.com/NVIDIA/hpc-container-maker/issues/367
+            force_add_repo=True,
             ospackages=[package],
             yum_keys=['https://developer.download.nvidia.com/devtools/repos/{0}/{1}/nvidia.pub'.format(self.__distro_label, self.__arch_label)],
             yum_repositories=['https://developer.download.nvidia.com/devtools/repos/{0}/{1}'.format(self.__distro_label, self.__arch_label)])
diff --git a/hpccm/building_blocks/packages.py b/hpccm/building_blocks/packages.py
index c524b35..272fd16 100644
--- a/hpccm/building_blocks/packages.py
+++ b/hpccm/building_blocks/packages.py
@@ -74,6 +74,11 @@ class packages(bb_base):
     if `download` is False. If empty, then the downloaded packages are
     not extracted. The default value is an empty string.
 
+    force_add_repo: Boolean flag to specify whether adding a
+    repository should be considered successful no matter the actual
+    result.  This parameter is only valid for yum repositories.  The
+    default value is False.
+
     ospackages: A list of packages to install.  The list is used for
     both Ubuntu and RHEL-based Linux distributions, therefore only
     packages with the consistent names across Linux distributions
@@ -140,6 +145,7 @@ class packages(bb_base):
         self.__extra_opts = kwargs.get('extra_opts', [])
         self.__extract = kwargs.get('extract', None)
         self.__epel = kwargs.get('epel', False)
+        self.__force_add_repo = kwargs.get('force_add_repo', False)
         self.__ospackages = kwargs.get('ospackages', [])
         self.__powertools = kwargs.get('powertools', False)
         self.__release_stream = kwargs.get('release_stream', False)
@@ -180,6 +186,7 @@ class packages(bb_base):
                         extra_opts=self.__extra_opts,
                         extract=self.__extract,
                         epel=self.__epel,
+                        force_add_repo=self.__force_add_repo,
                         keys=self.__yum_keys,
                         ospackages=ospackages,
                         powertools=self.__powertools,
diff --git a/hpccm/building_blocks/yum.py b/hpccm/building_blocks/yum.py
index 3d465cc..26fd687 100644
--- a/hpccm/building_blocks/yum.py
+++ b/hpccm/building_blocks/yum.py
@@ -58,6 +58,10 @@ class yum(bb_base):
     if `download` is False. If empty, then the downloaded packages are
     not extracted. The default value is an empty string.
 
+    force_add_repo: Boolean flag to specify whether adding a
+    repository should be considered successful no matter the actual
+    result.  The default value is False.
+
     keys: A list of GPG keys to import.  The default is an empty list.
 
     ospackages: A list of packages to install.  The default is an
@@ -104,6 +108,7 @@ class yum(bb_base):
         self.__epel = kwargs.get('epel', False)
         self.__extra_opts = kwargs.get('extra_opts', [])
         self.__extract = kwargs.get('extract', None)
+        self.__force_add_repo = kwargs.get('force_add_repo', False)
         self.__keys = kwargs.get('keys', [])
         self.__opts = ['-y']
         self.ospackages = kwargs.get('ospackages', [])
@@ -166,8 +171,12 @@ class yum(bb_base):
                 self.__commands.append('yum install -y yum-utils')
 
             for repo in self.__repositories:
-                self.__commands.append(
-                    'yum-config-manager --add-repo {}'.format(repo))
+                if self.__force_add_repo:
+                    self.__commands.append(
+                        '(yum-config-manager --add-repo {} || true)'.format(repo))
+                else:
+                    self.__commands.append(
+                        'yum-config-manager --add-repo {}'.format(repo))
 
         if self.__epel:
             # This needs to be a discrete, preliminary step so that


Test patch:
diff --git a/test/test_nsight_compute.py b/test/test_nsight_compute.py
index 013329a..8dc5e23 100644
--- a/test/test_nsight_compute.py
+++ b/test/test_nsight_compute.py
@@ -63,7 +63,7 @@ RUN wget -qO - https://developer.download.nvidia.com/devtools/repos/ubuntu1604/a
 r'''# NVIDIA Nsight Compute 2020.2.1
 RUN rpm --import https://developer.download.nvidia.com/devtools/repos/rhel8/x86_64/nvidia.pub && \
     yum install -y dnf-utils && \
-    yum-config-manager --add-repo https://developer.download.nvidia.com/devtools/repos/rhel8/x86_64 && \
+    (yum-config-manager --add-repo https://developer.download.nvidia.com/devtools/repos/rhel8/x86_64 || true) && \
     yum install -y \
         nsight-compute-2020.2.1 && \
     rm -rf /var/cache/yum/*''')
@@ -122,7 +122,7 @@ RUN wget -qO - https://developer.download.nvidia.com/devtools/repos/ubuntu1804/p
 r'''# NVIDIA Nsight Compute 2020.2.1
 RUN rpm --import https://developer.download.nvidia.com/devtools/repos/rhel7/ppc64le/nvidia.pub && \
     yum install -y yum-utils && \
-    yum-config-manager --add-repo https://developer.download.nvidia.com/devtools/repos/rhel7/ppc64le && \
+    (yum-config-manager --add-repo https://developer.download.nvidia.com/devtools/repos/rhel7/ppc64le || true) && \
     yum install -y \
         nsight-compute-2020.2.1 && \
     rm -rf /var/cache/yum/*''')
@@ -137,7 +137,7 @@ RUN rpm --import https://developer.download.nvidia.com/devtools/repos/rhel7/ppc6
 r'''# NVIDIA Nsight Compute 2020.2.1
 RUN rpm --import https://developer.download.nvidia.com/devtools/repos/rhel7/arm64/nvidia.pub && \
     yum install -y yum-utils && \
-    yum-config-manager --add-repo https://developer.download.nvidia.com/devtools/repos/rhel7/arm64 && \
+    (yum-config-manager --add-repo https://developer.download.nvidia.com/devtools/repos/rhel7/arm64 || true) && \
     yum install -y \
         nsight-compute-2020.2.1 && \
     rm -rf /var/cache/yum/*''')
diff --git a/test/test_nsight_systems.py b/test/test_nsight_systems.py
index bd17daa..2d3d128 100644
--- a/test/test_nsight_systems.py
+++ b/test/test_nsight_systems.py
@@ -63,7 +63,7 @@ RUN wget -qO - https://developer.download.nvidia.com/devtools/repos/ubuntu1604/a
 r'''# NVIDIA Nsight Systems 2021.1.1
 RUN rpm --import https://developer.download.nvidia.com/devtools/repos/rhel8/x86_64/nvidia.pub && \
     yum install -y dnf-utils && \
-    yum-config-manager --add-repo https://developer.download.nvidia.com/devtools/repos/rhel8/x86_64 && \
+    (yum-config-manager --add-repo https://developer.download.nvidia.com/devtools/repos/rhel8/x86_64 || true) && \
     yum install -y \
         nsight-systems-cli-2021.1.1 && \
     rm -rf /var/cache/yum/*''')
@@ -144,7 +144,7 @@ RUN wget -qO - https://developer.download.nvidia.com/devtools/repos/ubuntu1804/p
 r'''# NVIDIA Nsight Systems 2020.1.1
 RUN rpm --import https://developer.download.nvidia.com/devtools/repos/rhel7/ppc64le/nvidia.pub && \
     yum install -y yum-utils && \
-    yum-config-manager --add-repo https://developer.download.nvidia.com/devtools/repos/rhel7/ppc64le && \
+    (yum-config-manager --add-repo https://developer.download.nvidia.com/devtools/repos/rhel7/ppc64le || true) && \
     yum install -y \
         nsight-systems-cli-2020.1.1 && \
     rm -rf /var/cache/yum/*''')
@@ -159,7 +159,7 @@ RUN rpm --import https://developer.download.nvidia.com/devtools/repos/rhel7/ppc6
 r'''# NVIDIA Nsight Systems 2020.2.1
 RUN rpm --import https://developer.download.nvidia.com/devtools/repos/rhel7/arm64/nvidia.pub && \
     yum install -y yum-utils && \
-    yum-config-manager --add-repo https://developer.download.nvidia.com/devtools/repos/rhel7/arm64 && \
+    (yum-config-manager --add-repo https://developer.download.nvidia.com/devtools/repos/rhel7/arm64 || true) && \
     yum install -y \
         nsight-systems-cli-2020.2.1 && \
     rm -rf /var/cache/yum/*''')