Repository: NVIDIA/hpc-container-maker

Issue:
Add support for Ubuntu 24.04
Please add support for the recently released new LTS flavor of Ubuntu, ie. 24.04. hpccm is used by the GROMACS development team to build their CI images and we're keen to start testing on that version soon because it will become our minimum supported version. If there's things we can do to help, please suggest!

Discussion:

Patch:
diff --git a/.github/workflows/python3.yml b/.github/workflows/python3.yml
index 6e756ef..bfc0559 100644
--- a/.github/workflows/python3.yml
+++ b/.github/workflows/python3.yml
@@ -8,16 +8,7 @@ jobs:
     strategy:
       matrix:
         os: [ubuntu-latest, macos-latest, windows-latest]
-        python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12']
-        include:
-          - os: macos-latest
-            python-version: '3.5'
-          - os: macos-latest
-            python-version: '3.6'
-          - os: windows-latest
-            python-version: '3.5'
-          - os: windows-latest
-            python-version: '3.6'
+        python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
 
     steps:
     - uses: actions/checkout@v2
diff --git a/docs/misc_api.md b/docs/misc_api.md
index 0f0d392..417e932 100644
--- a/docs/misc_api.md
+++ b/docs/misc_api.md
@@ -90,9 +90,9 @@ __Arguments__
 
 
 - __distro (string)__: Valid values are `centos7`, `centos8`, `rhel7`,
-`rhel8`, `rockylinux8`, `ubuntu16`, `ubuntu18`, `ubuntu20`, and
-`ubuntu22`.  `ubuntu` is an alias for `ubuntu16`, `centos` is an
-alias for `centos7`, and `rhel` is an alias for `rhel7`.
+`rhel8`, `rockylinux8`, `rockylinux9`, `ubuntu16`, `ubuntu18`, `ubuntu20`,
+`ubuntu22`, and `ubuntu24`.  `ubuntu` is an alias for `ubuntu16`, `centos`
+is an alias for `centos7`, and `rhel` is an alias for `rhel7`.
 
 
 ## set_singularity_version
diff --git a/docs/primitives.md b/docs/primitives.md
index efc40c6..765e761 100644
--- a/docs/primitives.md
+++ b/docs/primitives.md
@@ -22,11 +22,11 @@ is `docker` (Singularity specific).
 
 - ___distro__: The underlying Linux distribution of the base image.
 Valid values are `centos`, `centos7`, `centos8`, `redhat`, `rhel`,
-`rhel7`, `rhel8`, `rockylinux8`, `ubuntu`, `ubuntu16`, `ubuntu18`,
-`ubuntu20`, and `ubuntu22`.  By default, the primitive attempts to
-figure out the Linux distribution by inspecting the image
-identifier, and falls back to `ubuntu` if unable to determine the
-Linux distribution automatically.
+`rhel7`, `rhel8`, `rockylinux8`, `rockylinux9`, `ubuntu`, `ubuntu16`,
+`ubuntu18`, `ubuntu20`, `ubuntu22`, and `ubuntu24`.  By default, the
+primitive attempts to figure out the Linux distribution by inspecting
+the image identifier, and falls back to `ubuntu` if unable to determine
+the Linux distribution automatically.
 
 - ___docker_env__: Boolean specifying whether to load the Docker base
  image environment, i.e., source
diff --git a/hpccm/config.py b/hpccm/config.py
index b14e616..b1734b7 100644
--- a/hpccm/config.py
+++ b/hpccm/config.py
@@ -174,9 +174,9 @@ def set_linux_distro(distro):
   # Arguments
 
   distro (string): Valid values are `centos7`, `centos8`, `rhel7`,
-  `rhel8`, `rockylinux8`, `ubuntu16`, `ubuntu18`, `ubuntu20`, and
-  `ubuntu22`.  `ubuntu` is an alias for `ubuntu16`, `centos` is an
-  alias for `centos7`, and `rhel` is an alias for `rhel7`.
+  `rhel8`, `rockylinux8`, `rockylinux9`, `ubuntu16`, `ubuntu18`, `ubuntu20`,
+  `ubuntu22`, and `ubuntu24`.  `ubuntu` is an alias for `ubuntu16`, `centos`
+  is an alias for `centos7`, and `rhel` is an alias for `rhel7`.
 
   """
   this = sys.modules[__name__]
@@ -201,6 +201,9 @@ def set_linux_distro(distro):
   elif distro == 'rockylinux8':
     this.g_linux_distro = linux_distro.ROCKYLINUX
     this.g_linux_version = Version('8.0')
+  elif distro == 'rockylinux9':
+    this.g_linux_distro = linux_distro.ROCKYLINUX
+    this.g_linux_version = Version('9.0')
   elif distro == 'ubuntu':
     this.g_linux_distro = linux_distro.UBUNTU
     this.g_linux_version = Version('16.04')
@@ -216,6 +219,9 @@ def set_linux_distro(distro):
   elif distro == 'ubuntu22':
     this.g_linux_distro = linux_distro.UBUNTU
     this.g_linux_version = Version('22.04')
+  elif distro == 'ubuntu24':
+    this.g_linux_distro = linux_distro.UBUNTU
+    this.g_linux_version = Version('24.04')
   else:
     logging.warning('Unable to determine the Linux distribution, defaulting to Ubuntu')
     this.g_linux_distro = linux_distro.UBUNTU
diff --git a/hpccm/primitives/baseimage.py b/hpccm/primitives/baseimage.py
index dd3e47a..6c1efec 100644
--- a/hpccm/primitives/baseimage.py
+++ b/hpccm/primitives/baseimage.py
@@ -50,11 +50,11 @@ class baseimage(object):
 
     _distro: The underlying Linux distribution of the base image.
     Valid values are `centos`, `centos7`, `centos8`, `redhat`, `rhel`,
-    `rhel7`, `rhel8`, `rockylinux8`, `ubuntu`, `ubuntu16`, `ubuntu18`,
-    `ubuntu20`, and `ubuntu22`.  By default, the primitive attempts to
-    figure out the Linux distribution by inspecting the image
-    identifier, and falls back to `ubuntu` if unable to determine the
-    Linux distribution automatically.
+    `rhel7`, `rhel8`, `rockylinux8`, `rockylinux9`, `ubuntu`, `ubuntu16`,
+    `ubuntu18`, `ubuntu20`, `ubuntu22`, and `ubuntu24`.  By default, the
+    primitive attempts to figure out the Linux distribution by inspecting
+    the image identifier, and falls back to `ubuntu` if unable to determine
+    the Linux distribution automatically.
 
     _docker_env: Boolean specifying whether to load the Docker base
      image environment, i.e., source
@@ -135,12 +135,16 @@ class baseimage(object):
             hpccm.config.set_linux_distro('rhel8')
         elif self.__distro == 'rockylinux8':
             hpccm.config.set_linux_distro('rockylinux8')
+        elif self.__distro == 'rockylinux9':
+            hpccm.config.set_linux_distro('rockylinux9')
         elif re.search(r'centos:?7', self.image):
             hpccm.config.set_linux_distro('centos7')
         elif re.search(r'centos:?8', self.image):
             hpccm.config.set_linux_distro('centos8')
         elif re.search(r'rockylinux:?8', self.image):
             hpccm.config.set_linux_distro('rockylinux8')
+        elif re.search(r'rockylinux:?9', self.image):
+            hpccm.config.set_linux_distro('rockylinux9')
         elif re.search(r'centos|rhel|redhat', self.image):
             hpccm.config.set_linux_distro('centos')
         elif re.search(r'ubi:?7', self.image):
@@ -155,6 +159,8 @@ class baseimage(object):
             hpccm.config.set_linux_distro('ubuntu20')
         elif re.search(r'ubuntu:?22', self.image):
             hpccm.config.set_linux_distro('ubuntu22')
+        elif re.search(r'ubuntu:?24', self.image):
+            hpccm.config.set_linux_distro('ubuntu24')
         elif re.search(r'ubuntu', self.image):
             hpccm.config.set_linux_distro('ubuntu')
         else:


Test patch:
diff --git a/test/test_config.py b/test/test_config.py
index bd71496..e67a8ef 100644
--- a/test/test_config.py
+++ b/test/test_config.py
@@ -68,6 +68,21 @@ class Test_config(unittest.TestCase):
                          hpccm.linux_distro.UBUNTU)
         self.assertEqual(hpccm.config.g_linux_version, Version('18.04'))
 
+        hpccm.config.set_linux_distro('ubuntu20')
+        self.assertEqual(hpccm.config.g_linux_distro,
+                         hpccm.linux_distro.UBUNTU)
+        self.assertEqual(hpccm.config.g_linux_version, Version('20.04'))
+
+        hpccm.config.set_linux_distro('ubuntu22')
+        self.assertEqual(hpccm.config.g_linux_distro,
+                         hpccm.linux_distro.UBUNTU)
+        self.assertEqual(hpccm.config.g_linux_version, Version('22.04'))
+
+        hpccm.config.set_linux_distro('ubuntu24')
+        self.assertEqual(hpccm.config.g_linux_distro,
+                         hpccm.linux_distro.UBUNTU)
+        self.assertEqual(hpccm.config.g_linux_version, Version('24.04'))
+
     @docker
     def test_set_linux_distro_centos(self):
         """Set Linux distribution to CentOS"""
@@ -112,6 +127,11 @@ class Test_config(unittest.TestCase):
                          hpccm.linux_distro.ROCKYLINUX)
         self.assertEqual(hpccm.config.g_linux_version, Version('8.0'))
 
+        hpccm.config.set_linux_distro('rockylinux9')
+        self.assertEqual(hpccm.config.g_linux_distro,
+                         hpccm.linux_distro.ROCKYLINUX)
+        self.assertEqual(hpccm.config.g_linux_version, Version('9.0'))
+
     @docker
     def test_set_linux_distro_invalid(self):
         """Set Linux distribution to an invalid value"""