Creating Images#

Important

Various commands that manipulate images execute as user root, thereby requiring that the commands internally use sudo and requiring that user root must have access to the workspace that contains the administrator's images. Typically the per-user workspace is ~/.scyldcw/workspace/. If that directory is not accessible to the command executing as root, then another accessible directory can be employed. You can identify that alternative path by adding a modimg.workspace setting to ~/.scyldcw/settings.ini.

The cw-install script creates an initial image named DefaultImage based on publicly available repositories that match the ClusterWareAI ™ head node operating system. If these repositories are not accessible, run the cw-add-boot-config tool later with locally accessible repositories as described in Creating Local Repositories without Internet.

There are multiple ways to create an image in the ClusterWareAI software.

Create Image from DefaultImage Clone#

A recommended best practice is to rarely and only very carefully modify DefaultImage. Instead, use DefaultImage as a stable baseline from which you clone new images.

  1. Use cw-imgctl to clone the DefaultImage to a new name, leaving the DefaultImage untouched. Image names, like names for other ClusterWareAI objects, must start with an alphabet character and cannot start with a number.

    cw-imgctl -i DefaultImage clone name=mpiImage
    
  2. Use cw-modimg to modify the cloned image:

    cw-modimg -i mpiImage --install openmpi3.1
    

See Modifying Images for additional details and examples.

Create Image from ISO or Repository#

You can create a new image from an ISO or network-accessible package repository. Before you begin, consider the source of the components (packages) for the new image. A distro ties together a list of repos (package repositories) and an optional release. The package_manager is determined during image creation, but can be overridden in the distro. The initial default distro matches the original head node's version, uses package_manager dnf, and downloads packages from a one item repos list.

  1. Determine the available distros on your head node. For example, this head node uses the Rocky 8 distro:

    [admin@virthead]$  cw-clusterctl distros ls -L
    Distros
      Rocky
        name: Rocky
        packaging: rpm
        release: 8
        repos
          Rocky_appstream
          Rocky_base
    
  2. List the available repos on your head node. The repo typically corresponds to the available distros. For example, the head node has a single repo that contains "Rocky_base":

    [admin@virthead]$ cw-clusterctl repos ls -L
    Repos
    Rocky_appstream
      keys: []
      name: Rocky_appstream
      urls
        http://dl.rockylinux.org/pub/rocky/$releasever/AppStream/$basearch/os/
    
    Rocky_base
      keys: []
      name: Rocky_base
      urls
        http://dl.rockylinux.org/pub/rocky/$releasever/BaseOS/$basearch/os/
    
  3. Use the cw-modimg tool to create a new image. In this example, the image is named "NewImg" and uses the default distro that downloads packages from the latest Rocky Yum repo:

    cw-modimg --create --set-name NewImg
    

To create a Rocky image that contains something other than the latest Rocky release, see Creating Arbitrary Rocky Images. To create a RHEL image, see Creating Arbitrary RHEL Images.

Create Image for Different Architecture#

The ClusterWareAI supports compute nodes with a different underlying architecture from the head nodes. For example, you can have an x86_64 head node and an ARM64/aarch64 compute node. You can build RHEL-based or Ubuntu images for different architectures on a head node and deploy them to a compute node with minimal additional steps.

Note

Creating an image for a different architecture from the head node takes 2-3 times longer than creating an image for the same architecture. On a modern head node, this should be just a few minutes.

Before creating images for another architecture, enable the QEMU container service on the head node via one of the following:

  • If you rarely create images for other architectures, manually enable the container service on a head node:

    systemctl start cw-qemu-static
    

    Manually enabling the container service is temporary and lasts until the next reboot.

  • If you create images for other architectures frequently, enable the container service on a head node at boot time.

    1. Enable the service on the head node manually:

      systemctl start cw-qemu-static
      
    2. Modify the /etc/containers/systemd/cw-qemu-static.container file and uncomment the [Install] section. This enables the service at boot time in the future.

As with other images, you can create a new image from an ISO or network-accessible package repository.

For example, to create a Rocky 9 image for aarch64 using a repository:

  1. Open the /etc/yum.repo.d/clusterware.repo file and review the baseurl line.

    • If your baseurl is pointing to localhost, no change is needed.

    • If your baseurl is pointing to repo.ice.penguinsolutions.com, update the baseurl value to:

      baseurl=https://<AUTHENTICATION_TOKEN>@repo.ice.penguinsolutions.com/clusterware/13/el<VERSION_ID>/x86_64/
      

      This ensures the image you create looks for the aarch64 client RPM files in the correct location.

  2. Create a repo that points to aarch64 for the latest version of Rocky 9 (version 9.8 in this example):

    cw-clusterctl repos create name=Rocky-9.8-aarch64-minimal-repo \
       urls='https://dl.rockylinux.org/pub/rocky/9/BaseOS/aarch64/os/'
    
  3. Create a distro that references the new repo:

    cw-clusterctl distros create name=Rocky-9.8-aarch64-minimal-distro \
       repos=Rocky-9.8-aarch64-minimal-repo release=9
    
  4. Create an image that references the new distro:

    cw-modimg --create Rocky-9.8-aarch64-minimal-distro \
      --set-name Rocky-9.8-aarch64-minimal-image --no-discard --upload --overwrite
    
  5. Create a boot configuration that references the new image:

    cw-add-boot-config --image Rocky-9.8-aarch64-minimal-image \
       --boot-config Rocky-9.8-aarch64-minimal-boot
    
  6. Review the release field in the details of the boot configuration to confirm that the architecture is aarch64:

    [admin@virthead]$ cw-bootctl -i Rocky-9.8-aarch64-minimal-boot ls -l
    Rocky-9.8-aarch64-minimal-boot
      cmdline: enforcing=0
      description: Boot configuration generated by scyld-add-boot-config
      image: Rocky-9.8-aarch64-minimal-image
      initramfs
        chksum: sha1:24cc15c0786ff98b147a8b8f828bd1d9dbba7c92
        filename: ddc50c8035e641d0919d9d63ee433cb9
        mtime: 2026-07-21 15:01:24 UTC (2 days, 23:08:15 ago)
        size: 49.0 MiB (51357260 bytes)
      kernel
        chksum: sha1:2592b2053edc158562b1e25c1092da1c4b9584ed
        filename: 9e8e5eb65e0c4de2a8b363c93c8c7aae
        mtime: 2026-07-21 15:01:23 UTC (2 days, 23:08:16 ago)
        size: 12.4 MiB (13052760 bytes)
      last_modified: 2026-07-21 15:01:24 UTC (2 days, 23:08:15 ago)
      name: Rocky-9.8-aarch64-minimal-boot
      release: 5.14.0-570.17.1.el9_6.aarch64
    

If you are creating an Ubuntu image, the repo points to the public Ubuntu ports repository instead of the archive and the distro should reference the arm64 architecture.

For example, to create an Ubuntu image for aarch64 using a repository:

  1. Create a repo that points to the public Ubuntu ports repository:

    cw-clusterctl repos create name=ports.ubuntu.com \
       urls=http://ports.ubuntu.com/ubuntu-ports/
    
  2. Create a distro that references the new repo and specifies the packaging, release, and architecture:

    cw-clusterctl distros create repos=ports.ubuntu.com packaging=deb \
       release=noble arch=arm64 name=ubuntu-noble-arm64
    
  3. Create the image and boot configuration:

    cw-add-boot-config --distro ubuntu-noble-arm64 --image ubuntu-noble-arm64-image \
       --boot-config ubuntu-noble-arm64-boot