Registry VM Templates and Tags

VM Templates and Tags

Once a VM has been tagged, it becomes a “VM Template”. The VM template & tag’s state cannot be permanently modified unless you create a new tag, post-changes. This is very reminiscent of how git commit works. You can execute commands and modify the state of the VM after tagging it, but it will not save the changes until you create a new tag. This is important to consider when using the Anka Build Cloud Registry since it will only push the state of the VM when the tag was created, not after.

In summary, when cloning a tagged VM you have two options:

  1. Shallow Clone from the current VM state, regardless of the state when it was tagged (anka clone {source} {clone}).
  2. Shallow Clone the state of a VM template & tag by targeting the tag by name (anka clone --tag {tagName} {source} {clone}), regardless of what has been done to it since tagging.
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                  

❯ 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 |

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.

ARM USERS: Suspending will currently stop the VM. It will show as suspended, regardless.

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)

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 not a typical workflow, but is possible. 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 {PROJECT_NAME}.
  2. Push this to the Registry with anka push {PROJECT_NAME} --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 {PROJECT_NAME} {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 {PROJECT_NAME} 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.