55* Pulls signed macOS and Windows OCI artifacts from Quay into a ``signed/`` directory.
66* Restores supplementary files (readme, license, changelog) that were held during signing.
77* Compresses each file entry into the final deliverable format:
8- - macOS / Linux → ``.tar.gz`` (from ``os/arch/`` directory)
8+ - macOS / Linux (non-disk-image) → ``.tar.gz`` (from ``os/arch/`` directory)
9+ - Linux disk images (``.qcow2``, ``.iso``) → copied as-is to ``ready_for_distribution/``
910 - Windows → ``.zip`` (from ``os/arch/`` directory, extension corrected from
1011 ``.tar.gz``/``.tar``)
1112* Updates ``SNAPSHOT_JSON`` to reflect corrected Windows filenames in ``files[]``.
3940
4041PROG = "compress_artifacts.py"
4142
43+ # File extensions that identify disk images. These files are copied as-is to
44+ # ready_for_distribution without being wrapped in a tar archive.
45+ _DISK_IMAGE_EXTENSIONS : frozenset [str ] = frozenset ({".qcow2" , ".iso" })
46+
4247QUAY_SECRET_MOUNT = Path (os .environ .get ("QUAY_SECRET_MOUNT" , "/mnt/quaySecret" ))
4348CONTENT_DIR = Path (os .environ .get ("CONTENT_DIR" , "/shared/artifacts" ))
4449SHARED_DIR = Path (os .environ .get ("SHARED_DIR" , "/shared" ))
@@ -111,11 +116,10 @@ def _compress_file_entry(
111116 the archive is created as a ``.zip`` instead of ``.tar.gz``/``.tar``, and the returned
112117 source path reflects the corrected filename so the snapshot can be updated accordingly.
113118
114- Raises RuntimeError on failure (missing source, unknown OS, or empty arch directory).
119+ Disk images (``.qcow2``, ``.iso``) are copied directly to ``ready_dir`` without
120+ being wrapped in a tarball, since they are already in their final deliverable format.
115121
116- Note: all files are currently compressed regardless of type. ISOs should be
117- passed through as-is rather than wrapped in a tarball — this will need to be
118- addressed before ISO delivery is supported.
122+ Raises RuntimeError on failure (missing source, unknown OS, or empty arch directory).
119123 """
120124 source = entry .get ("source" )
121125 if not source :
@@ -139,12 +143,22 @@ def _compress_file_entry(
139143
140144 # macOS and Linux follow the Unix convention of tar.gz archives; Windows uses zip
141145 # because that is the standard expected by Windows users and Developer Portal tooling.
146+ # Disk images are an exception: they are delivered as-is without any archiving.
142147 if os_name in ("darwin" , "linux" ):
143148 out_path = ready_dir / source_filename
144- with tarfile .open (str (out_path ), "w:gz" ) as tf :
145- for item in sorted (arch_dir .rglob ("*" )):
146- if item .is_file ():
147- tf .add (str (item ), arcname = str (item .relative_to (arch_dir )))
149+ if Path (source_filename ).suffix .lower () in _DISK_IMAGE_EXTENSIONS :
150+ files = [f for f in arch_dir .rglob ("*" ) if f .is_file ()]
151+ if len (files ) != 1 :
152+ raise RuntimeError (
153+ f"Expected exactly one disk image file in { arch_dir } , "
154+ f"found { len (files )} "
155+ )
156+ shutil .copy2 (str (files [0 ]), str (out_path ))
157+ else :
158+ with tarfile .open (str (out_path ), "w:gz" ) as tf :
159+ for item in sorted (arch_dir .rglob ("*" )):
160+ if item .is_file ():
161+ tf .add (str (item ), arcname = str (item .relative_to (arch_dir )))
148162 logger .info (" Created (%s): %s" , array_name , source_filename )
149163 return source
150164
0 commit comments