Registry VM Templates and Tags

VM Templates and Tags

Once a VM has been tagged, it becomes a “VM Template”. The Tag can be thought of as a commit in a git repository. The commit will always be there, even if you were to later on remove the code you added to the repo/codebase in that specific commit. Therefore, the VM Template Tag and anything created from it will always be there, even if you were to later on remove the data from the VM and create a new tag. This is important to consider when using the Anka Build Cloud Registry.

Clones are not automatically tagged.
❯ anka list | grep test
| test (v1)                                 | ff06aa5b-0825-4f86-b5d0-c1cdb39fcedf | Jan 25 13:15:10 2022 | stopped |

❯ anka clone --tag v1 test test3                  
8a4e0033-29b4-4c29-8a0c-51fa53093d1c

❯ anka list | grep test         
| test3                                     | 8a4e0033-29b4-4c29-8a0c-51fa53093d1c | Feb 3 12:01:34 2022  | stopped |
| test (v1)                                 | ff06aa5b-0825-4f86-b5d0-c1cdb39fcedf | Jan 25 13:15:10 2022 | stopped |

In the above example, test3 is a shallow clone of test and has a new UUID. The underlying layers are shared with test and will be used when test3 is started.

Our Recommendation for Templates

If you’re managing multiple templates for multiple teams and projects, you want to share as many underlying layers in the hierarchy of VM Templates as possible. To do this, we typically recommend:

  1. Create a VM with macOS 13.0.1 and also name it that. The, push or locally tag it as vanilla.
  2. Start the 13.0.1 VM and add the dependencies that everyone would need (typically git and brew). Stop the VM and modify to add port forwarding. Push/locally tag this as brew+git+portforwarding22.
  3. Clone from 13.0.1 (with the brew+git+portforwarding22 tag) and create 13.0.1-xcode14.1. Start it and install Xcode. Stop it and push it with any tag name. I use v1 usually.
  4. Clone from 13.0.1-xcode14.1 and create 13.0.1-xcode14.1-{projectNameHere}-v1 which you’ll install all of that projects dependencies in and push with any tag name.

This allows everything to share the underlying layers that are the same (since they’re all cloned from 13.0.1) and optimize disk space. You can then just pull the last VM template in the hierarchy and create a new one when needed, telling the teams to point to the new one when ready.

If it helps, here is it visually:

13.0.1 (stopped)  | 
                  | -> clone -> 13.0.1-xcode14.1 (stopped) |
                  |                                        | -> clone -> 13.0.1-xcode14.1-project1-v1 (with fastlane-v1.X) (suspended)
                  |                                        | -> clone -> 13.0.1-xcode14.1-project2-v1 (with fastlane-v2.X) (suspended)
                  |                                        | -> clone -> 13.0.1-xcode14.1-project2-v2 (with fastlane-v2.X) (suspended)
                  |
                  | -> clone -> 13.0.1-xcode13.4.1 (stopped) -> clone -> 13.0.1-xcode13.4.1-project3-v1 (suspended)
ARM USERS: Suspending will currently stop the VM. It will show as suspended, regardless.
Important: When you tag a VM you cannot remove the data from the layers that make up the VM unless you do a full clone. When you go to shallow clone a VM/create a new tag, it may be beneficial to start from the tag/layers before you last made changes so that you don’t include the data/layers and disk usage with the new tag you’re creating.

Replacing a Template in the Registry but keep its Name and UUID

Sometimes you’ll want to replace an existing VM Template in the Registry with a brand new one instead of pushing a new tag with minor changes to the original Template. This is useful to fix a UUID/Template for each Team that will use VM Templates with their own dependencies installed inside. There are some important things to understand though:

  • A VM Template’s Tags in the Registry are versioned starting with 0 (the original tag pushed) and increase with subsequent pushes (1, 2, 3, etc).
  • If Tag 0 and 1 exist, 0 cannot be deleted without deleting 1 as well. This same thing applies to three tags like 0, 1, 2, and deleting 1 will delete 2 but keep 0.

In the situation of Tag 0 being the only tag for a Template, and then wanting to replace it, you’ll want to do the following:

  1. Create an empty VM using anka create TeamA.
  2. Push this to the Registry with anka push TeamA --tag empty

You will now have an empty VM in the registry, not consuming any space, but with a specific UUID (8cdd7656-9d84-4c7b-bcd2-8f541ad9be11 for example). You can now push a second VM (with a totally different UUID) on top of the one in the Registry and have it adopt 8cdd7656-9d84-4c7b-bcd2-8f541ad9be11 as its UUID:

anka push --remote-vm TeamA {NEW_VM_NAME} --tag V1

Now if you want to replace Tag V1 with a new VM, but have it be under the same name, UUID, and even Tag name, you can revert the previous version with anka registry revert TeamA and push.

Avoid reverting Tag 0 as it will delete the entire Template from the Registry.
The --remote-vm CLI option can be dangerous as pushing a completely independent VM on top of another can orphan previous tags (if it has data) and cause your Registry to run out of disk space. Be sure to revert before pushing.