Skip to content

Creating and maintaining OS images with OSTree

OSTree is a Git-like tool that maintains and updates immutable system images. When you manage images with OSTree, each image is tracked as a branch in a repository with a history of commits. OSTree branches are also called refs. The active OS that runs on a device is the live system. The live system is deployed from a specific commit from a specific branch.

When you update an image, OSTree pulls the latest commit from the remote branch and checks it out locally next to the commit deployed in the live system. The system is then restarted and it uses the new commit as the active OS. The prior deployment is still available and you can manually boot into it or perform a rollback to reactivate the older commit. You can also remove older OS versions to avoid unnecessary disk use.

Creating an OSTree-based image

AutoSD manifests support the ostree image type. Building images based on the ostree image type happens in two stages:

  • An OSTree commit is created with all of the content required for the image.
  • A bootable system is created by pulling and deploying the new OSTree commit.

Prerequisites

Procedure

  1. Include the --ostree-repo option when you build your image to use OSTree to update an existing OSTree repo or create a new one. The --ostree-repo option grants access to the intermediate OSTree commit:

    sudo ./auto-image-builder.sh build --target qemu --mode image --ostree-repo <ostree-repo> \
    --define 'distro_version="1"' --export qcow2  <path>/<my-manifest>.mpp.yml <my-image>.qcow2
    

    The example command builds the <my-image>.qcow2 image and extracts the OSTree commits generated during the build. It also pulls the commits into the local ostree-repo directory. If a pre-existing ref exists in the repo, the commit ID of the existing ref becomes the parent commit of the new image to create an unbroken history of commits for your OSTree images. Also notice that the distro_version equals 1; in a later procedure, you will increment this value to distinguish one build from another.

  2. Inspect the OSTree repo commit history:

    $ ostree refs --repo=ostree-repo
    cs9/x86_64/<repo>
    
    $ ostree log --repo=ostree-repo cs9/x86_64/<repo>
    commit cda4ca283008c01cb8e70a83d58faea66a075869b0e1bab402af3c0c3706d40c
    ContentChecksum:  fddbdb184f0c5f5984120bca1dbe11756446a2f38750d54858b37220064ec19b
    Date:  2024-10-14 17:41:42 +0000
    Version: 1
    (no subject)
    
  3. Run the image:

    sudo ./automotive-image-builder/automotive-image-runner <my-image>.qcow2
    
  4. After the image boots, log in as root using the password password.

  5. From the image console, verify the status of ostree-repo:

    # rpm-ostree status
    State: idle
    Deployments:
    ● auto-sig:cs9/x86_64/<repo>
                       Version: 1 (2024-10-14T17:41:42Z)
                        Commit: cda4ca283008c01cb8e70a83d58faea66a075869b0e1bab402af3c0c3706d40c
    

    In this example, there is only one ref installed, cs9/x86_64/<repo>. The dot symbol (●) indicates the active commit. Notice that the remote from which the ref was installed is auto-sig. For more information about the remote, run the following command:

    # ostree remote list -u
    auto-sig  http://10.0.2.100/
    

    The default URL is http://10.0.2.100/. You can override the URL by changing the ostree_repo_url, but keeping the default URL is beneficial. The default URL is significant, because it matches the URL used by the automotive-image-runner --publish-dir command. Keeping the default URL enables the VM that contains your image to receive updates from the auto-sig remote.

Updating OSTree-based images

When you update your image and run auto-image-builder.sh, the newly created image overwrites the one you previously built. Creating an OSTree repo prevents you from overwriting images. When you use an OSTree repo to manage images, each new version of your image has a unique commit ID.

Prerequisites

Procedure

  1. Include the --publish-dir option when you launch the image with automotive-image-runner to expose the ostree-repo directory from your host to the VM:

    sudo ./automotive-image-builder/automotive-image-runner --publish-dir=ostree-repo <my-image>.qcow2
    

    Note

    If you receive a message similar to Command 'netcat' not found in path, ignoring publish-dir, install netcat on your host machine and run the image again.

  2. After the image boots, log in as root using the password password.

  3. Try to update the system:

    # rpm-ostree upgrade
    1 metadata, 0 content objects fetched; 469 B transferred in 0 seconds; 0 bytes content written
    No upgrade available.
    

    The system is already running on the latest version of the branch, so no upgrades are available.

  4. Update your image by using the --define variable to add an extra RPM and change the distro_version:

    sudo ./auto-image-builder.sh build --target qemu --mode image --ostree-repo <ostree-repo> \
    --define 'distro_version="1.1"' --define 'extra_rpms=["curl"]' --export qcow2  <path>/<my-manifest>.mpp.yml <my-image>.repo
    

    Using the .repo extension instead of .qcow2 indicates to OSTree that you are updating or iterating on an image rather than creating a new image. The updated image is added to the OSTree repo as a new ref with a unique commit ID.

  5. Run ostree log again to see the new commit ID and its parent commit, which form the commit history for the ref:

    $ ostree log --repo=ostree-repo cs9/x86_64/<repo>
    commit 9935018979dee13c0f0b666963fb3170052926c4df6018acac027d22e0d6d951
    Parent:  cda4ca283008c01cb8e70a83d58faea66a075869b0e1bab402af3c0c3706d40c
    ContentChecksum:  c71978c831aa9950071840488d5edf935a8d2bfe219c162f817b3b2cebed2890
    Date:  2024-10-14 19:44:39 +0000
    Version: 1.1
    (no subject)
    
    commit cda4ca283008c01cb8e70a83d58faea66a075869b0e1bab402af3c0c3706d40c
    ContentChecksum:  fddbdb184f0c5f5984120bca1dbe11756446a2f38750d54858b37220064ec19b
    Date:  2024-10-14 17:41:42 +0000
    Version: 1
    (no subject)
    
  6. Run the image:

    sudo ./automotive-image-builder/automotive-image-runner --publish-dir=ostree-repo <my-image>.qcow2
    
  7. After the image boots, log in as root using the password password.

  8. Upgrade the system to fetch updates from the OSTree repo, create a new deployment, and install the changes:

    # rpm-ostree upgrade
    15 metadata, 3 content objects fetched; 6220 KiB transferred in 2 seconds; 24.3 MB content written
    Scanning metadata: 1821...done
    Staging deployment...done
    Run "systemctl reboot" to start a reboot
    
  9. Check the status of the OS image deployment:

    # rpm-ostree status
    State: idle
    Deployments:
      auto-sig:cs9/x86_64/<repo>
                       Version: 1.1 (2024-10-14T18:19:51Z)
                        Commit: 262e882d5c74da5315f712720529f599df415a1519f6efc1247edf96e148ed788
    
    ● auto-sig:cs9/x86_64/<repo>
                       Version: 1 (2024-10-14T17:41:42Z)
                        Commit: cda4ca283008c01cb8e70a83d58faea66a075869b0e1bab402af3c0c3706d40c
    

    The rpm-ostree status command exposes the incremental image update located on the remote ostree-repo directory to the VM.

  10. Notice that the extra curl RPM you added is not found, because a reboot is required to complete the upgrade:

    # curl http://10.0.2.100/config
    -bash: curl: command not found
    
  11. Reboot the system to deploy the new version 1.1 of your image:

    systemctl reboot
    
  12. After the system reboots, log in as root using the password password.

  13. Check the status of the OS image deployment:

    # rpm-ostree status
    State: idle
    Deployments:
    ● auto-sig:cs9/x86_64/<repo>
                       Version: 1.1 (2024-10-14T18:19:51Z)
                        Commit: 262e882d5c74da5315f712720529f599df415a1519f6efc1247edf96e148ed788
    
      auto-sig:cs9/x86_64/<repo>
                       Version: 1 (2024-10-14T17:41:42Z)
                        Commit: cda4ca283008c01cb8e70a83d58faea66a075869b0e1bab402af3c0c3706d40c
    
  14. Verify that the upgrade worked:

    # curl http://10.0.2.100/config
    [core]
    repo_version=1
    mode=archive-z2
    

    The output of the verification command shows that the upgrade was success because curl is available and the VM can access the OSTree repo.


© Red Hat