Anka
@veertuinc
This is a packer plugin for building macOS VM templates and tags using the Anka Virtualization CLI
- Community
Updated 2 months ago
- GitHub(opens in new tab)
Anka VM Clone
Type: veertu-anka-vm-clone
The veertu-anka-vm-clone Packer builder is able to clone existing Anka VM Templates for use with the Anka Virtualization package and the Anka Build Cloud. The builder takes a source VM name, clones it, and then runs any provisioning necessary on the new VM Template before stopping or suspending it.
The builder does not manage templates. Once a template is created, it is up to you to use it or delete it.
Important Notes
In Anka 3.0 we now require a tagged source VM before cloning in order to share the underlying .ank image and optimize disk space. If your source VM is not tagged yet, we will assign one . We highly recommend pushing this VM Template/Tag to your registry so disk usage is optimized.
Interrupted or failed builds: With Packer's -on-error=ask, choosing [a] abort without cleanup leaves the cloned VM on disk for inspection (no anka delete). Choosing [c] clean up still removes it. See issue #94.
Configuration Reference
There are many configuration options available for the builder. They are segmented below into two categories: required and optional parameters.
Required Configuration
source_vm_name(String) The VM to clone for provisioning, either stopped or suspended.type(String) Must beveertu-anka-vm-clone.
Optional Configuration
vm_name(String) The name for the VM that is created.Generated using the source_vm_name if not provided: (
{{ source_vm_name }}-{10RandomChars}).Ignored when
skip_cloneistrue.vcpu_count(String) The number of vCPU cores, defaults to2.ram_size(String) The size in "[0-9]+G" format, defaults to2G.disk_size(String) The size in "[0-9]+G" format, defaults to25G.We will automatically resize the internal disk for you by executing
diskutil apfs resizeContainerinside of the VM. The plugin resolves the APFS container fromdiskutil info /ordiskutil apfs list. IMPORTANT: Changing the clone's disk size will break the layer sharing with the root and double disk space usage. Change the disk size of the source template, then clone from it instead.stop_vm(Boolean) Whether or not to stop the vm after it has been created, defaults to false.display_controller(string) The display controller to set (runanka modify VMNAME set display --helpto see available options).always_fetch(Boolean) Always pull the source VM from the registry. Defaults to false.Example: pull-and-clone-existing.pkr.hcl
skip_clone(Boolean) Do not clonesource_vm_name. The builder starts, modifies, and provisionssource_vm_nameitself, then stops or suspends it. Defaults tofalse.The build changes
source_vm_namein place.vm_nameis ignored. The builder still pullssource_vm_namewhen it is not local, or whenalways_fetchistrue. Resource and property settings (vcpu_count,ram_size,disk_size,port_forwarding_rules,vm_label, and others) apply tosource_vm_name.The builder does not delete
source_vm_namewhen the build fails or when you usepacker build -force.The artifact name is
source_vm_name. Thus theveertu-anka-registry-pushpost-processor pushes a newtagonto the same registry template, and you do not needremote_vm. Do not setdelete_template_post_push = trueunless you want the post-processor to deletesource_vm_nameafter the push.Examples:
- skip-clone-with-post-processing.pkr.hcl (Anka Registry tag)
- skip-clone-with-thin-oci-tags.pkr.hcl (
thin_oci_pulls+ thin OCI push)
boot_delay(String) The time to wait before running packer provisioner commands, defaults to7s.wait_for_networking(Boolean) When enabled (the default), afterboot_delaythe builder runsanka runwith a short shell loop thatpings8.8.8.8until one reply succeeds (up to 120 attempts, one second apart) so basic guest connectivity is up before Packer continues—for example before shell provisioners thatcurlthe internet. Set tofalseto skip that step. The check runs afterboot_delayand does not changeboot_delayitself. If your environment blocks ICMP to8.8.8.8, set this tofalseand use another strategy (such as a longerboot_delayor a provisioner that retries).log_level(String) Set todebugto stream Anka debug lines to the Packer UI while commands run. You can also setANKA_LOG_LEVEL=debugon the host. The plugin captures debug throughANKA_LOG_FILEon a FIFO. It does not pass--debug. Failed Anka commands print the captured debug even whenlog_levelis unset.cacert(String) Path to a CA Root certificate.cert(String) Path to your node's client certificate to use for registry communication (if certificate authorization is enabled).insecure(Boolean) Skip TLS verification.key(String) Path to your node's client certificate key, if thecertcertificate doesn't contain one, to use for registry communication (if certificate authorization is enabled).cacert,cert,insecure, andkeyare only for an Anka Registry. The build fails if you set them whenremoteis an OCI registry URL, becauseanka pulldoes not accept them.hw_uuid(String) (Anka 2 only) The Hardware UUID you wish to set (usually generated withuuidgen).Example: clone-existing-with-hwuuid.pkr.hcl
port_forwarding_rules(Struct)If port forwarding rules are already set and you want to not have them fail the packer build, use
packer build --force.port_forwarding_guest_port(Int)port_forwarding_host_port(Int)port_forwarding_rule_name(String)
host_directory_mounts(Struct) (Anka 3.9.0+, Apple Silicon only)Persists host directory mounts in the VM template using
anka modify mount. Mounted folders appear under/Volumes/My Shared Files/in the guest.host_path(String) Absolute path to the host directory to mount.guest_folder_name(String) Optional guest folder name under/Volumes/My Shared Files/. Defaults to the host path's folder name.
vm_label(Struct) Assign, rename, or delete Anka VM labels (anka modify … label). Repeat the block for each label operation.Example: clone-existing-with-labels.pkr.hcl
name(String) Label key (required except fordelete_all).value(String) Label value (set only).delete(Boolean) Delete the label named byname.set_name(String) Rename: current name isname, new name isset_name.delete_all(Boolean) Delete all labels on the VM.
registry-path(String) The registry URL (will use your default configuration if not set).remote(String) The registry name or URL (will use your default configuration if not set).This takes priority in Anka 3 and
registry-pathwill be ignored.(Anka 3.9.0+) To pull the source VM as a full OCI tag, set
remoteto an OCI registry URL: anoci://URL, or anhttp(s)://URL with/v2in its path (for exampleoci://registry.example.com/v2/veertu/). The builder then runsanka pullinstead ofanka registry pull. A remote name fromanka registry addalways usesanka registry pull.thin_oci_pulls(Struct) (Anka 3.10.0+) Thin OCI tags to pull ontosource_vm_namebefore the clone. Repeat the block for each thin tag. The builder pulls them in the order you write them, each withanka pull --thin, after the source VM is local and has a tag.The pulls change
source_vm_nameitself: the thin tags stay on the source VM after the build.Each pull is always thin. A full pull after thin tags removes those thin tags, so a full tag can only be the source VM itself (local, or pulled with
remoteandsource_vm_tag).Examples:
- clone-existing-with-thin-oci-tags.pkr.hcl (clone, then thin push)
- skip-clone-with-thin-oci-tags.pkr.hcl (
skip_clone, multiple thin pulls, then thin push)
url(String) Required. The OCI tag to pull: anoci://URL, or anhttp(s)://URL with/v2in its path (for exampleoci://ghcr.io/homebrew/core/cmake:4.3.4).transform(List of String)sedexpressions that change the file paths of this layer. Each one becomes ananka pull --transformoption, in order (for example["s|cmake/4.3.4|usr/local"]).
thin_oci_pulls { url = "oci://ghcr.io/homebrew/core/cmake:4.3.4" transform = ["s|cmake/4.3.4|usr/local"] } thin_oci_pulls { url = "oci://ghcr.io/homebrew/core/ninja:1.13.2" transform = ["s|ninja/1.13.2|opt/homebrew"] }Anka does not relocate the
@@HOMEBREW_PREFIX@@/@@HOMEBREW_CELLAR@@placeholders in Homebrew bottles. Only bottles that link no other Homebrew libraries (cellar :any_skip_relocation, for examplecmakeandninja) run after a thin pull.source_vm_tag(String) Specify the tag of the VM we want to clone instead of using the default. Also the tag to target when pulling from the registry (defaults to latest tag).Example: pull-and-clone-existing.pkr.hcl
update_addons(Boolean) (Anka 2 only) Update the vm addons. Defaults to false.use_anka_cp(Boolean) Use built in anka cp command. Defaults to false.
Example
Here is an example that uses the file and shell provisioners.
Also see clone-existing.pkr.hcl and clone-existing-with-file-provisioner.pkr.hcl.
variable "source_vm_name" {
type = string
default = "anka-packer-base-macos"
}
variable "vm_name" {
type = string
default = "anka-packer-from-source"
}
source "veertu-anka-vm-clone" "clone" {
vm_name = "${var.vm_name}"
source_vm_name = "${var.source_vm_name}"
}
build {
sources = [
"source.veertu-anka-vm-clone.clone",
]
provisioner "file" {
destination = "/private/tmp/"
source = "./examples/ansible"
}
provisioner "shell" {
inline = [
"[[ ! -d /tmp/ansible ]] && exit 100",
"touch /tmp/ansible/test1"
]
}
provisioner "file" {
destination = "./"
direction = "download"
source = "/private/tmp/ansible/test1"
}
provisioner "shell-local" {
inline = [
"[[ ! -f ./test1 ]] && exit 200",
"rm -f ./test1"
]
}
}