OpenNebula's OneGate

OneGate is a metadata repository for VMs. Each VM can access it in an exclusive way by means of a unique token created at deployment time. It works as a key/value store, in the form <variable name> = <alphanumerical value>. If the VM is part of a service, i.e., a OneFlow application, then the service orchestrator can also access the store. In fact, OneGate is the mechanism used to exchange information between the VM(s) and OneFlow.

Each VM has its own namespace, so variables with the same name but belonging to different VMs can co-exist. As already explained, this is the rationale for OneFlow's elasticity rules.

The definition of variables and the criteria to update them is up to the user, as well as the script(s), or any other mechanism, to perform the operation.

Enable OneGate

The template of a VM can instruct OneGate to allcoate a new namespace. In particular, the option Add OneGate token in the Context section should be checked (see the red square in the following picture).

OneGate token option

This triggers the generation of a context disk, which is attached to the VM as a CDROM to the first available channel of the IDE bus (i.e., the device hda, if no other CDROM images have been added by the user. Some distributions may set up the device /dev/cdrom or emulate the SCSI interface for the cdrom, so that the device is accessible as /dev/sr0 or /dev/sr1 ...).

Important note: the token can be generated only if the user profile defines the property TOKEN_PASSWORD. In order to check that, simply open the user's settings by means of the drop-down menu in the top right corner.

The user settings menu

In the Info panel check for the entry TOKEN_PASSWORD.

The token password

If missing you can create it at any time. In the previous screen, scroll to the bottom and enter a new property with that name and a 40 characters alphanumerical string as value (do not forget to click on Add).

New token password

The TOKEN_PASSWORD will be used to sign the VM token. In fact the string should be nothing but the SHA1 sum of a password. If you need to create one, you can just type dd if=/dev/urandom count=1 status=none|sha1sum or openssl rand 32 -base64|sha1sum on a Linux terminal and copy the 40 characters alphanumerical output string into the form. Many thanks to Nick Waterman, VA3NNW, Principal Infrastructure Architect for pointing this out.

Access and usage

The contextualisation disk contains all the info to access OneGate, namely the IP address and the token. The user should mount the contextualisation disk and

  • source the script context.sh so that the environment variable ONEGATE_ENDPOINT (the IP of the OneGate server, reachable only from within the IPs assigned to the VMs) is available;
  • assign the content of the file token.txt to another environment variable, i.e., ONEGATE_TOKEN, which is the actual token.

From now on, any tool capable of sending HTML messages (i.e., curl or wget) can write into OneGate and query it, provided that the two following headers are defined in the message:

  • X-ONEGATE-TOKEN: the token, as contained in the file token.txt on the contextualisation disk;
  • X-ONEGATE-VMID: the numerical ID of the VM whose namespace should be accessed.

OneGate exposes to the VMs an API which allows the following operations:

  • Request VM info: send a GET request to ${ONEGATE_ENDPOINT}/vm;
  • Write VM info: send a PUT request to ${ONEGATE_ENDPOINT}/vm;
  • Query the service (if the VM is part of a OneFlow application: send a GET request to ${ONEGATE_ENDPOINT}/service);
  • Fetch the endpoints: it returns (as variable vm_info) the address of the namespace of the VM whose ID is in the header and the address of the service (as variable service_info).

The output of the API call is in JSON format.

A concrete example

The example proposed here is based on the OpenNebula documentation. The goal is to use a bash script to update the LOAD variable (expressing how intensively the VM is used) into the OneGate's namespace of the VM and read it back.

Mount the CDROM (attached to the primary IDE channel) and list the content:

# mount /dev/hda /media/
mount: block device /dev/hda is write-protected, mounting read-only
# ls /media/
context.sh  token.txt

Source the file context.sh and copy the token into the variable ONEGATE_TOKEN (from the file token.txt)

# source /media/context.sh
# ONEGATE_TOKEN=$(cat /media/token.txt)

At this point, just refer to OneGate as $ONEGATE_ENDPOINT and to the token by means of $ONEGATE_TOKEN. Please also note that the context file defines the environment variable VMID with the numerical ID of the VM.

In order to fetch the info about the VM stored by OneGate, enter the following curl command:

# curl -X "GET" "${ONEGATE_ENDPOINT}/vm" --header "X-ONEGATE-TOKEN: $ONEGATE_TOKEN" --header "X-ONEGATE-VMID: $VMID"

{"VM":{"NAME":"Ubuntu token-8811","USER_TEMPLATE":{"SUNSTONE_NETWORK_SELECT":"YES","HYPERVISOR":"kvm","SUNSTONE_CAPACITY_SELECT":"YES"},"TEMPLATE":{"NIC":[{"NETWORK":"MWN_access_103","MAC":"02:00:00:67:00:04"}]},"ID":"8811"}}

where the options passed to curl are:

  • -X: the request type, namely GET (retrieve) and PUT (store) are significant in our case;
  • --header: the headers that are expected by OneGate on top of the HTML ones. Two headers are needed (the token and the VM identifier), so the option should be used two times.

The command to store is very similar

# curl -X "PUT" "${ONEGATE_ENDPOINT}/vm" --header "X-ONEGATE-TOKEN: $ONEGATE_TOKEN" --header "X-ONEGATE-VMID: $VMID" -d "LOAD = $(uptime |awk '{load=100*$NF;print load}')"

The few differences are:

  • the request type is now PUT since the data should be stored;
  • there is the need to pass the data to be stored, see the option -d in the curl command.

The data has always the form <key> = <value>, enclosed by double quotes ("). As already mentioned when explaining the example, the custom variable we want to store (key) is named LOAD. The value is calculated on the fly by means of another bash command (the $( ... ) signs). This command consists of executing the shell utility uptime and taking the last word of its output (the load in the last 15 minutes, see the man page). For the string parsing, the awk tool is employed. The output of uname is fed into awk (see the pipe, |), which takes the last column (in awk the default word, or column, separator is the space and the macro $NF identifies the last occurrence), it multiplies it by 100 (uptime uses decimal numbers, we want a percentage here), storing the result in the local variable load, and it finally prints the result (print load).

A short note on the load average reported by uptime. It takes into account the number of processes that are currently using the CPU and those that are queuing to access the resource. The real load depends on the number of Virtual CPUs of the VM. With one Virtual CPU a load beyond 1.0 is problematic. On the other hand, with two Virtual CPUs, a load of 1.0 is perfectly fine, it means that only one can cope with the load. In this case, a load of 2.0 would be worrisome. With four Virtual CPUs, the threshold would be 4.0 and so on. A more detailed explanation can be found here.

If the namespace of the VM is queried again

# curl -X "GET" "${ONEGATE_ENDPOINT}/vm" --header "X-ONEGATE-TOKEN: $ONEGATE_TOKEN" --header "X-ONEGATE-VMID: $VMID"
{"VM":{"NAME":"Ubuntu token-8811","USER_TEMPLATE":{"SUNSTONE_NETWORK_SELECT":"YES","HYPERVISOR":"kvm","LOAD":"85","SUNSTONE_CAPACITY_SELECT":"YES"},"TEMPLATE":{"NIC":[{"NETWORK":"MWN_access_103","MAC":"02:00:00:67:00:04"}]},"ID":"8811"}}

the new variable shows up in the USER_TEMPLATE section, with a value of 85.

Final remarks

  • the namespace is strictly private. It can be accessed only via the token, which is unique for each VM, even if generated from the same template;
  • OneFlow can access the namespace of all VMs. If the VMs are part of a service, then OneGate is the right tool to support elasticity rules;
  • OneGate is not a way to exchange information between VMs, it is rather a way to communicate to the service orchestrator when the VMs are part of an elastic application.