Contextualizing Virtual Machines 3.2

There are two contextualization mechanisms available in OpenNebula: the automatic IP assignment, and a more generic way to give any file and configuration parameters. You can use any of them individually, or both. {{INLINETOC}} ====== Using Virtual Network Leases within a Virtual Machine ====== With OpenNebula you can derive the IP address assigned to the VM from the MAC address using the MAC_PREFFIX:IP rule. In order to achieve this we provide context scripts for Debian, Ubuntu, CentOS and openSUSE based systems. These scripts can be easily adapted for other distributions, check [[http://dev.opennebula.org/projects/opennebula/repository/show/share/scripts|dev.opennebula.org]]. To configure the Virtual Machine follow these steps:
:!: These actions are to configure the VM, the commands refer to the VMs root file system
* Copy the script ''$ONE_SRC_CODE_PATH/share/scripts/vmcontext.sh'' into the ''/etc/init.d'' directory in the VM root file system. * Execute the script at boot time before starting any network service, usually runlevel 2 should work. $ ln /etc/init.d/vmcontext.sh /etc/rc2.d/S01vmcontext.sh Having done so, whenever the VM boots it will execute this script, which in turn would scan the available network interfaces, extract their MAC addresses, make the MAC to IP conversion and construct a ''/etc/network/interfaces'' that will ensure the correct IP assignment to the corresponding interface. ====== Generic Contextualization ====== The method we provide to give configuration parameters to a newly started virtual machine is using an ISO image (OVF recommendation). This method is network agnostic so it can be used also to configure network interfaces. In the VM description file you can specify the contents of the iso file (files and directories), tell the device the ISO image will be accessible and specify the configuration parameters that will be written to a file for later use inside the virtual machine. {{ documentation:rel1.4:contextualization.png?350 |}} In this example we see a Virtual Machine with two associated disks. The Disk Image holds the filesystem where the Operating System will run from. The ISO image has the contextualization for that VM: * ''context.sh'': file that contains configuration variables, filled by OpenNebula with the parameters specified in the VM description file * ''init.sh'': script called by VM at start that will configure specific services for this VM instance * ''certificates'': directory that contains certificates for some service * ''service.conf'': service configuration
:!: This is just an example of what a contextualization image may look like. Only ''context.sh'' is included by default. You have to specify the values that will be written inside ''context.sh'' and the files that will be included in the image.
:!: To prevent regular users to copy system/secure files, the ''FILES'' attribute within ''CONTEXT'' is only allowed to OpenNebula users within the oneadmin group.
====== Defining Context ====== In VM description file you can tell OpenNebula to create a contextualization image and to fill it with values using ''CONTEXT'' parameter. For example: CONTEXT = [ hostname = "MAINHOST", ip_private = "$NIC[IP, NETWORK=\"public net\"]", dns = "$NETWORK[DNS, NETWORK_ID=0]", root_pass = "$IMAGE[ROOT_PASS, IMAGE_ID=3]", ip_gen = "10.0.0.$VMID", files = "/service/init.sh /service/certificates.$UID /service/service.conf" ] Variables inside CONTEXT section will be added to ''context.sh'' file inside the contextualization image. These variables can be specified in three different ways: * **Hardcoded variables:** hostname = "MAINHOST" * **Using template variables** * ''$'': any single value variable of the VM template, like for example:\\ip_gen = "10.0.0.$VMID" * ''$[]'': Any single value contained in a multiple value variable in the VM template, like for example:ip_private = $NIC[IP] * ''$[, =]'': Any single value contained in a multiple value variable in the VM template, setting one attribute to discern between multiple variables called the same way, like for example:ip_public = "$NIC[IP, NETWORK=\"Public\"]". You can use any of the attributes defined in the variable, NIC in the previous example. * **Using Virtual Network template variables** * ''$NETWORK[, =]'': Any single value variable in the Virtual Network template, like for example:dns = "$NETWORK[DNS, NETWORK_ID=3]"Note that the network MUST be in used by any of the NICs defined in the template. The vnet_attribute can be ''TEMPLATE'' to include the whole vnet template in XML (base64 encoded). * **Using Image template variables** * ''$IMAGE[, =]'': Any single value variable in the Image template, like for example:root = "$IMAGE[ROOT_PASS, IMAGE_ID=0]"Note that the image MUST be in used by any of the DISKs defined in the template. The image_attribute can be ''TEMPLATE'' to include the whole image template in XML (base64 encoded). * **Using User template variables** * ''$USER[]'': Any single value variable in the user (owner of the VM) template, like for example:ssh_key = "$USER[SSH_KEY]"The user_attribute can be ''TEMPLATE'' to include the whole user template in XML (base64 encoded). * **Pre-defined variables**, apart from those defined in the template you can use: * ''$UID'', the uid of the VM owner * ''$TEMPLATE'', the whole template in XML format and encoded in base64 The file generated will be something like this: # Context variables generated by OpenNebula hostname="MAINHOST" ip_private="192.168.0.5" dns="192.168.4.9" ip_gen="10.0.0.85" files="/service/init.sh /service/certificates.5 /service/service.conf" target="sdb" root="13.0" Some of the variables have special meanings, but none of them are mandatory: ^ Attribute ^ Description ^ | **files** | Files and directories that will be included in the contextualization image | | **target** | device where the contextualization image will be available to the VM instance. Please note that the proper device mapping may depend on the guest OS, e.g. ubuntu VMs should use hd* as the target device |
:!: A default target attribute is [[.:template#disks_device_mapping | generated automatically]] by OpenNebula as "hdb" or "sdb", depending on the default prefix set at [[.:oned_conf#image_repository | oned.conf]]. You can set here any other value, but you have to take into account the other disks defined in the VM template to avoid collisions.
====== Using Context ====== The VM should be prepared to use the contextualization image. First of all it needs to mount the contextualization image somewhere at boot time. Also a script that executes after boot will be useful to make use of the information provided. The file ''context.sh'' is compatible with ''bash'' syntax so you can easilly source it inside a shellscript to get the variables that it contains. ====== EXAMPLE ====== Here we propose a way to use this contextualization data. Each unix has their own filesystem layout and way of handling init scripts, this examples assumes a debian-based virtual machine. We are going to use contextualization data to set the hostname, the IP address and a user with known ssh keys. First thing, lets outline the ''CONTEXT'' section of the VM template: CONTEXT = [ hostname = "$NAME", ip_public = "$NIC[IP, NETWORK=\"Public\"]", username = virtualuser files = "/vms_configuration/id_rsa.pub /vms_configuration/init.sh" ] The OpenNebula front-end will thus require a ''/vms_configuration'' folder with: * ''id_rsa.pub'': Public ssh key to be added to the trusted ssh keys of the new user * ''init.sh'': script that will perform the configuration. Explained below. Now we will need to configure the VM to make use of this data. We are going to place in ''/etc/rc.local'' as: #!/bin/sh -e mount -t iso9660 /dev/sdc /mnt if [ -f /mnt/context.sh ]; then . /mnt/init.sh fi umount /mnt exit 0 We use an indirection (rc.local calls init.sh) so changing the script means editing a file locally rather that changing it inside the VMs. The init.sh script will be the one actually doing the work: #!/bin/bash if [ -f /mnt/context.sh ]; then . /mnt/context.sh fi hostname $HOSTNAME ifconfig eth0 $IP_PUBLIC useradd -m $USERNAME mkdir -p ~$USERNAME/.ssh cat /mnt/id_rsa.pub >> ~$USERNAME/.ssh/authorized_keys chown -R $USERNAME /home/$USERNAME