Using Anka Controller

Anka Controller is the central management system of Anka Build and provides a simple and extensible interface for provisioning and managing on-demand macOS VMs on a cluster of mac hardware (Anka Build nodes). If you use CI tools like Jenkins or Teamcity, integrate them with Anka controller using controller REST APIs to provision macOS VMs on-demand for CI job requests. For Jenkins, use the Anka Build plugin.

Using Anka Controller

After the successful installation of Anka Controller, Controller must be configured to communicate with Anka Registry, the Anka nodes, and your CI system.

By default, Anka Controller setup doesn’t use HTTPS or TLS. To configure HTTPS and/or TLS on the controller, you can contact for additional setup instructions.

Now, connect your Anka nodes (any Apple hardware running the Anka Build application package) with the Controller by running this command sudo ankacluster join -g on each of the Anka Build nodes (mac machines on which you have installed ankabuild.pkg). It’s recommended to use the -g flag with join and disjoin commands.

ankacluster join --help
   ankacluster join - join a cluster

   ankacluster join [command options] http://controller-address[:port]

   --queue-address value, -q value        queue-address[:port] (optional)
   --max-vm-count NUMBER, -m NUMBER       Maximum NUMBER of VMs this node is allowed to run (optional) (default: 2)
   --name NAME, -n NAME                   Node NAME alias (optional)
   --tls, -t                              Use tls for communicating with the queue (optional)
   --keystore PATH, -k PATH               PATH to certificate and keystore (PEM, PKCS12) (optional)
   --keystore-pass PASSWORD, -p PASSWORD  PASSWORD for certificate and keystore (optional)
   --cacert PATH, -c PATH                 PATH to CA bundle file (PEM/X509) (optional)
   --global, -g                           Install agent into system domain

In the command, http://controller-address[:port] is the Controller IP.

If your controller is configured on port 80, then leave the [:port] empty. Else, specify the port no.

--max-vm-count value variable is used to set a max limit of concurrent VMs that can be run on the node through the controller. For example if you are using mac minis for your build or test jobs, you want to limit to 2 concurrent VMs. On a Mac Pro, you can configure a higher value.

--name is used to associate a specific name to this Build node. When setting up Anka Build cloud on multiple build nodes, name value parameter identifies each of these nodes.

sudo ankacluster join -g -m 6 -n 228mpro http://XX.XXX.XXX.XXX:8090
Testing connection to controller...: Ok
Testing connection to the registry...: Ok
Testing connection to the queue...: Ok
Cluster join success

To disjoin a build node from a cluster, use the following command.

sudo ankacluster disjoin -g

Adding/Removing build nodes dynamically

You can add or remove build nodes from Anka macOS cloud in a dynamic fashion by executing sudo ankacluster join -g & sudo ankacluster disjoin -g from the build nodes. This does not impact your CI job execution. Controller automatically distributes the jobs across available(joined) nodes. You can also use COntroller REST APIs to disjoin nodes.

Accessing and working with controller management UI

In release 1.2, we introduced a web UI service to controller. Access it by going to your controller IP -

You can view the status of your Anka Build macOS cloud from this UI and also perform basic management operations.

Dashboard View

This view displays the total active build nodes, running VM instances, instance run capacity utilization, registry storage consumption, average cpu and ram utilization across the entire cloud.


Nodes View

Click on nodes to go to node list view.

You can view all active build nodes, instances running on them, their cpu and ram utilization. From this view, you can modify the concurrent VM capacity for each node.


Templates View

Click on templates to look at all VMs stored in the registry.


Click on an individual template to view all versions/tags for that template.


Click on distribute to all nodes or select specific Nodes to pre-load the most frequently used Vm templates for your build/test jobs on all build nodes. This will reduce the time for first time job execution on Anka Build cloud. Controller manages disk space on the Build Nodes and deletes VM templates that are not used for CI build and test jobs.

Note - Once a job executes on a build node in a specific VM, the original VM template used for this job is cached on the node. Hence, any subesequent job executions don’t download VM from the registry. The VM template is only downloaded when there is a brand new VM template or a new tag to an existing VM template. Download of a VM template with a new tag is only incremental.


Distribution to nodes is complete.


Instances View

Click on Instances to get a list of all running instances on the cloud.


Manually starting instances

Click on create instance to manually start instances using a specific VM template/tag on the cloud.


Accessing Error logs

Starting from Controller release version 1.0.12, logs will be available for download from the Controller Management portal for error scenarios during VM provisioning.



Controller REST APIs

Use the REST APIs to integrate Anka Build cloud with your CI system. For Jenkins, use the Anka Jenkins Plugin, and for Teamcity, use the Anka Teamcity Plugin.

To provision and start VMs (Start VM instance will start N count of instances of a particular type across the node cluster) Note - Group_id and priority is only available if you are running Enterprise and higher tier of Anka Build.

url= "/api/v1/vm", 
body="VM UUID, tag, version, count, node_id, startup_script, group_id, priority"  
(node_id, count, tag, version, startup_script and group_id are optional. If tag is not provided, the latest version will be used, otherwise whatever tag is specified will be pulled on the nodes. By default count is 1. If node_id is not specified the VM could be scheduled on any node)
startup_script is base64 encoded string of the script to be executed after the instance is started
Group_id lets you choose on which group the vm will run on
Priority lets you give the vm priority over other vms, most urgent priority is 1 and the default priority is 1000
Returns: Operation Result, Array of instance UUIDs
Example Body: {"vmid":"226d946b-2467-11e7-84b7-a860b60fd826", “count”=10, startup_script=”IyEvYmluL2Jhc2gNCmV4cG9ydCBBPSJhYWEiDQoNCg==”}

To terminate VM

url= "/api/v1/vm", 
body=Instance ID
Example Body:  {"id":"7ed72625-ee2e-4195-606a-dd04a274b9c3"}
Returns: Operation result

To list the instances

url= "/api/v1/vm"
Returns: Operation result, List of initiated VM instance UUIDs 

To show information for an instance

url= "/api/v1/vm?id={instance_id}"
Returns: Operation result, State, VM and connectivity info

To list all build nodes joined to the controller

url= "/api/v1/node"
Returns: Operation result, List of nodes IDs

To show information for a build node

url= "/api/v1/node?id={node_id}"
Returns: Operation result, State and Info of the node

To delete/remove a build node from controller database/portal. This doesnot remove the node from the cluster. Use ankacluster disjoin on the node to disjoin the node from the cluster. Then, execute delete/remove node API call to remove it permanently from the controller database.

url= "/api/v1/node"
body=node_id ID
Example Body:  {"node_id":"7ed72625-ee2e-4195-606a-dd04a274b9c3"}
Returns: Operation result

To list all VM templates accessible to controller from the registry

url= "/api/v1/registry/vm"
Returns: Operation result, List of registry VM UUIDs and names

To show information on a specific VM template from the registry

url= "/api/v1/registry/vm?id={vm_id}"
Returns: Operation result, VM UUID, name and tag list

To delete a specific VM template and all associated tags from the registry

url= "/api/v1/registry/vm?id={vm_id}"
Returns: Operation result

To delete a specific VM template-tag and all later tags from the registry. For this call use the IP:port of the registry.

Url: "/registry/revert?id={vm_id}&tag_name={tobedeletedtag}"
Method: DELETE
vm_id - must
Version - the version number to delete, all newer versions will be deleted as well
Tag_name - specify tag name instead of numeric value
If neither version or tag_name is supplied the latest version will be deleted
{“status”: “OK”} / {“status”: “error”}

To distribute a specific VM template to all build nodes Group_id is only available if you are running Enterprise tier of Anka Build.

url= "/api/v1/registry/vm/distribute"
body="VM Uuid,  tag, version, group id" 
group_id (optional) distributes the image to a specific group
Example Body: {"template_id":"226d946b-2467-11e7-84b7-a860b60fd826", “tage”=”v1”}
Returns: Operation result, request id

To get distribution status

url= "/api/v1/registry/distribute?id={request_id}"
Returns: Operation result, map of node id -> (distribution status, template id, tag, version, time)

Note - Group management APIs are only available in Enterprise and higher Anka Build Tier To get a list of all groups definied

List Groups
url= "/api/v1/group"
Returns: Operation result, List of groups

To create a new Group

url= "/api/v1/group"
body="Name, Description" 
Example Body: {"name": "My awesome group", "description": "my favorite nodes"}
Returns: Operation result, The new group

To update a Group

url= "/api/v1/group?id={group_id}"
body=”Name, Description”
 Example Body: {"name": "My other awesome group", "description": "my second favorite nodes"}
Returns: Operation result

To delete a Group

url= "/api/v1/group?id={group_id}"
Returns: Operation result

To add nodes to a Group

Add Nodes To Groups 
url= "/api/v1/node/group"
body="Groupd Ids,  Node Ids" 
Example Body: {"group_ids": ["a2a833a1-e44c-4247-57d1-6cd06b0fd040", "47f0a57e-9b14-4d80-4f5c-3284f2c85e0d"], "node_ids": ["c6493f47-7106-4cb9-88be-1f5cf2af7a72"]}
Returns: Operation result

To remove nodes from a group

url= "/api/v1/node/group"
body="Groupd Ids,  Node Ids" 
Example Body: {"group_ids": ["a2a833a1-e44c-4247-57d1-6cd06b0fd040", "47f0a57e-9b14-4d80-4f5c-3284f2c85e0d"], "node_ids": ["c6493f47-7106-4cb9-88be-1f5cf2af7a72"]}
Returns: Operation result