OpenNebula
From IEETA
Description | Managing Cloud Computing with OpenNebula |
---|---|
Date | 2013/02/23 |
Version | 3.8.1 |
Type | Wiki guide |
Download |
Note
The Windows contextualization part was written from scratch by André Monteiro and Tiago Batista as additional task to their research thesis; the remaining was based on the official OpenNebula guide. Please feel free to request more info or comments to andremonteiro_at_ua.pt & tsbatista_at_ua.pt .
Installing OpenNebula
The [1] shows how to install OpenNebula from the binary packages. Please read the Planning the Installation guide before you proceed.
Package Installation (Front-End)
Visit the software menu to download the latest package for your distribution. OpenNebula may be included in your official distribution package repositories, but you should check if it is the latest version and download it from our page instead.
Then proceed to install the packages with the corresponding package manager for your distribution or head to Building from Source Code guide if there are no packages for it.
CentOS platform notes
Before installing:
activate Karan Extras Repo. Enable [kbs-CentOS-Testing] in kbsingh-CentOS-Extras.repo. activate the EPEL repo.
openSUSE platform notes
Before installing:
activate the PackMan repo.
Installation Layout (Front-End)
After installing the opennebula packages the following directory structure will be used
Ruby Libraries Requirements (Front-End)
Some OpenNebula components need ruby libraries. OpenNebula provides a script that installs the required gems as well as some development libraries packages needed.
As root execute:
# /usr/share/one/install_gems
The previous script is prepared to detect common linux distributions and install the required libraries. If it fails to find the packages needed in your system, manually install these libraries:
sqlite3 development library mysql client development library curl development library libxml2 and libxslt development libraries ruby development library expat development library
If you want to install only a set of gems for an specific component read Building from Source Code where it is explained in more depth.
The following is required for the Front-End:
ruby >= 1.8.7
Requirements (Hosts)
You don't need to install any OpenNebula component in your hosts. These are the only requirements in the host machines:
ssh server running hypervisor working properly configured ruby >= 1.8.7
User & Group (Unix Accounts) (Front-End & Hosts)
The OpenNebula package installation creates a new user and group named oneadmin in the front-end. This account will be used to run the OpenNebula services and to do regular administration and maintenance tasks. That means that you eventually need to login as that user or to use the ”sudo -u oneadmin” method.
The hosts need also this user created and configured. Make sure you change the uid and gid by the ones you have in the frontend.
Get the user and group id of oneadmin. This id will be used later to create users in the hosts with the same id. In the front-end, execute as oneadmin:
$ id oneadmin uid=1001(oneadmin) gid=1001(cloud) groups=1001(cloud)
In this case the user id will be 1001 and group also 1001. Then log as root in your hosts and follow these steps:
Create the oneadmin group. Make sure that its id is the same as in the frontend. In this example 1001:
# groupadd --gid 1001 oneadmin
Create the oneadmin account, we will use the OpenNebula var directory as the home directory for this user.
# useradd --uid 1001 -g oneadmin -d /var/lib/one oneadmin
You can use any other method to make a common oneadmin group and account in the nodes, for example NIS.
Secure Shell Access (Front-End)
You need to create ssh keys for the oneadmin user and configure the host machines so it can connect to them using ssh without need for a password.
This section assumes that the directory /var/lib/one is shared by the front-end and all the hosts
(check the shared FS section for hints about using NFS).
Follow these steps in the front-end:
Generate oneadmin ssh keys:
$ ssh-keygen
When prompted for password press enter so the private key is not encrypted. Append the public key to ~/.ssh/authorized_keys to let oneadmin user log without the need to type a password.
$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
Many distributions (RHEL/CentOS for example) have permission requirements for the public key authentication to work:
$ chmod 700 ~/.ssh/
$ chmod 600 ~/.ssh/id_dsa.pub
$ chmod 600 ~/.ssh/id_dsa
$ chmod 600 ~/.ssh/authorized_keys
Tell ssh client to not ask before adding hosts to known_hosts file. This is configured into ~/.ssh/config, see man ssh_config for a complete reference.:
$ cat ~/.ssh/config Host * StrictHostKeyChecking no
Finally, check that the sshd daemon is running in the hosts. Also remove any Banner option from the sshd_config file in the hosts. If you exported /var/lib/one, then oneadmin should be able to log in the hosts without being prompt for a password.
If you are not going to export /var/lib/one via a shared FS, such as NFS, then you must copy the front-end /var/lib/one/.ssh
directory to each one of the hosts; in the same path.
Starting OpenNebula (Front-End)
Log in as the oneadmin user follow these steps:
Set oneadmin's OpenNebula credentials (username and password) adding the following to ~/.one/one_auth (change password for the desired password):
$ mkdir ~/.one $ echo "oneadmin:password" > ~/.one/one_auth $ chmod 600 ~/.one/one_auth
You are ready to start the OpenNebula daemons:
$ one start
Remember to always start OpenNebula as oneadmin!
Verifying the Installation
After OpenNebula is started for the first time, you should check that the commands can connect to the OpenNebula daemon. In the front-end, run as oneadmin the command onevm:
$ onevm list ID USER GROUP NAME STAT CPU MEM HOSTNAME TIME
If instead of an empty list of VMs you get an error message, then the OpenNebula daemon could not be started properly:
$ onevm list Connection refused - connect(2)
The OpenNebula logs are located in /var/log/one, you should have at least the files oned.log and sched.log, the core and scheduler logs. Check oned.log for any error messages, marked with [E].
The first time OpenNebula is started, it performs some SQL queries to check if the DB exists and if it needs a bootstrap.
You will have two error messages in your log similar to these ones, and can be ignored:
[ONE][I]: Checking database version. [ONE][E]: (..) error: no such table: db_versioning [ONE][E]: (..) error: no such table: user_pool [ONE][I]: Bootstraping OpenNebula database.
Next Steps
Now that OpenNebula is installed, follow the Basic Configuration guide to configure the software for you infrastructure.
OpenNebula comes with additional components that can be optionally started. Read the following guides to know which other components are included with the distribution:
- Sunstone GUI Server
- Acct & Stats
- Introduction to oZones
- Public Cloud servers to expose EC2 and OCCI interfaces
Configuring OpenNebula
Basic Configuration 3.8
This is the official guide from the OpenNebula Project page. Its aim is to give pointers to configure all the components available in OpenNebula. It is assumed that the infrastructure is prepared and OpenNebula is correctly installed.
Therefore, the following sections cover each specific component of OpenNebula that can be tailored and/or configured to better adjust the OpenNebula installation to the particular needs of your infrastructure and the potential cloud users.
Hypervisor
The most basic configuration you will have to do is related with the hypervisor technology installed in your hosts. By default OpenNebula comes with KVM drivers activated but you can also select other drivers and modify the driver configuration to tune some of its parameters. To know more about these components you can read the Virtualization Subsystem guide.
Host Monitoring
The next step is configuring the host monitoring. IM (Information Manager) driver should match the Virtualization driver we have configured as both will deal with the hypervisor. You can leave this as it is if you are going to use KVM or read the Host Subsystem guide to change or configure it.
Storage
Default OpenNebula configuration is prepared to use a shared filesystem between the frontend and hosts to store the images used by the running VMs. This driver is called shared, if you want to change it you can use the Storage Subsystem guide as a reference.
Networking
OpenNebula is able to manage a simple networking model using bridges to communicate but this is not the only networking model. You can learn more about the various networking options and configurations in the Networking Subsystem guide.
Managing Users and Groups
OpenNebula features various authentication and authorization mechanisms. There are wide array of choices, from builtin methods, to out-of-the-box external components or even the possibility to develop new mechanisms. A good entry point to this information is the Auth susbsystem overview. The guides to manage users and their permissions are here:
Sunstone Web Interface
This component is an easy to use web interface with the same functionality as the CLI. Comes with wizards that ease the creation of OpenNebula objects (VMs, networks, etc) and is a good entry point for the users of your resources. The guide to configure this component is at Sunstone GUI Server.
Accounting and Statistics
To gather information on the usage of the resources to do accounting and generate graphs for Sunstone there is another component that needs to be running. Read Acct & Stats guide to learn how to use this component.
OpenNebula Zones
The oZones component lets us manage various instances of OpenNebula and make shards from them. With it you'll be able to manage the resources on every zone and create more intricate deployments. The guide is at Introduction to oZones.
Hybrid Clouds
A Hybrid Cloud is an extension of a Private Cloud to combine local resources with resources from remote Cloud providers. OpenNebula offers the possibility of integration with a public cloud provider in order to satisfy peak demands, for which the local infrastructure is not enough. A good starting point is this nice introduction to the Hybrid Cloud possibilities using OpenNebula.
Public Cloud Interfaces
Aside from standard CLI and Sunstone we can ask for resources in an OpenNebula installation using public cloud interfaces. Two public interfaces are packed within the distribution: the EC2 Query interface and the Open Cloud Computing Interface (OCCI). The document that guides the installation of these servers is at Introduction to Public Cloud Computing
Using Linux Images for new Virtual Machines
Contextualizing Virtual Machines 3.8
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.
- Using Virtual Network Leases within a Virtual Machine
- Generic Contextualization
- Defining Context
- Using Context
- EXAMPLE
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. This scripts can be easily adapted for other distributions, check 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 VN 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.
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. There are security issues using this method. The problem and a workaround is explained in the Storage Subsystem guide.
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
- $<template_variable>: any single value variable of the VM template, like for example:\\
ip_gen = "10.0.0.$VMID"
- $<template_variable>[<attribute>]: Any single value contained in a multiple value variable in the VM template, like for example:
ip_private = $NIC[IP]
- $<template_variable>[<attribute>, <attribute2>=<value2>]: 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[<vnet_attribute>, NETWORK_ID=<vnet_id>]: 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.
- Using Image template variables
- $IMAGE[<image_attribute>, IMAGE_ID=<img_id>]: 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.
- 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<br>
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 |
<code>A default target attribute is generated automatically by OpenNebula as “hdb” or “sdb”, depending on the default prefix set at 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
Using Windows Images for new Virtual Machines
All of the example templates for ONE are for Unix systems. What about Windows? There are some restrictions to use it, not being free and licence keys are usual problems. Apart from that, Windows seems a little bit trickier than others, but after finding the right formula is as easy to deploy!
Preparing Windows Scripts/Context files
Executing all the scripts on startup and overriding privileges can be hard. We've managed to found a solution, may not be the most elegant, but it works.
We need the following files:
SetupComplete.cmd
SetupComplete.cmd is a file which is really helpful, because it can quietly be called as a startup script on Windows. Basically, it calls a VBScript on the attached context-created disk D. If the system has been syspreped, it erases the unattend file, to protect the installation credentials.
cscript //b d:/startup.vbs del /Q /F c:\windows\system32\sysprep\unattend.xml del /Q /F c:\windows\panther\unattend.xml
startup.vbs
This Visual Basic script, which can be called from a regular command prompt on boot, must run with privileges to modify script executing on the machine. Therefore it is called by the previous file SetupComplete.cmd on Windows startup. About its functions, it calls the Powershell console with unrestriced policy to execute the Powershell script on context-created disk D. Afterwards, it creates a new directory just to allow the admin user to ensure the script execution.
Set objShell = CreateObject("Wscript.Shell") objShell.Run("powershell -NonInteractive -NoProfile -NoLogo -ExecutionPolicy Unrestricted -file D:\one-context.ps1") Dim objFSO, objFolder Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFolder = objFSO.CreateFolder("C:\executedVBScript")
one-context.ps
This was the most difficult script to write, because it had many walls to break. The Powershell script runs to configure the new VM as a whole.
################################################################# ##### Windows Powershell Script to configure OpenNebula VMs ##### ##### Created by andremonteiro@ua.pt and tsbatista@ua.pt ##### ##### DETI/IEETA Universidade de Aveiro 2011 ##### ################################################################# Set-ExecutionPolicy unrestricted -force # not needed if already done once on the VM [string]$computerName = "$env:computername" [string]$ConnectionString = "WinNT://$computerName" function getContext($file) { $context = @{} switch -regex -file $file { '(.+)="(.+)"' { $name,$value = $matches[1..2] $context[$name] = $value } } return $context } function addLocalUser($context) { # Create new user $username = $context["username"] $ADSI = [adsi]$ConnectionString if(!([ADSI]::Exists("WinNT://$computerName/$username"))) { $user = $ADSI.Create("user",$username) $user.setPassword($context["password"]) $user.SetInfo() } # Already exists, change password else{ $admin = [ADSI]"WinNT://$env:computername/$username" $admin.psbase.invoke("SetPassword", $context["PASSWORD"]) } # Set Password to Never Expires $admin = [ADSI]"WinNT://$env:computername/$username" $admin.UserFlags.value = $admin.UserFlags.value -bor 0x10000 $admin.CommitChanges() # Add user to local Administrators $groups = "Administrators", "Administradores" foreach ($grp in $groups) { if([ADSI]::Exists("WinNT://$computerName/$grp,group")) { $group = [ADSI] "WinNT://$computerName/$grp,group" if([ADSI]::Exists("WinNT://$computerName/$username")) { $group.Add("WinNT://$computerName/$username") } } } } function getIp($mac) { $mac = $mac.Replace("-",":") $octet = $mac.Split(":") [String] $ip = "" $ip += [convert]::toint32($octet[2],16) $ip += "."+[convert]::toint32($octet[3],16) $ip += "."+[convert]::toint32($octet[4],16) $ip += "."+[convert]::toint32($octet[5],16) return $ip } function getGateway($mac) { $octet = $mac.Split(":") [String] $ip = "" $ip += [convert]::toint32($octet[2],16) $ip += "."+[convert]::toint32($octet[3],16) $ip += "."+[convert]::toint32($octet[4],16) $ip += ".254" return $ip } function configureNetwork($context) { $Nics = Get-WMIObject Win32_NetworkAdapterConfiguration | where {$_.IPEnabled -eq "TRUE" -and ($_.MACAddress)} foreach ($nic in $Nics) { [String]$mac = $nic.MACAddress [String]$ip = getIp($mac) [String]$gw = getGateway($mac) $nic.ReleaseDHCPLease() $nic.EnableStatic($ip , "255.255.255.0") $nic.SetGateways($gw) $DNSServers = "193.136.172.20", "193.136.171.21" $nic.SetDNSServerSearchOrder($DNSServers) $nic.SetDynamicDNSRegistration("TRUE") $nic.SetWINSServer($DNSServers[0], $DNSServers[1]) } } function renameComputer($context) { $ComputerInfo = Get-WmiObject -Class Win32_ComputerSystem $ComputerInfo.rename($context["HOSTNAME"]) } function enableRemoteDesktop() { # Windows 7 only - add firewall exception for RDP netsh advfirewall Firewall set rule group="Remote Desktop" new enable=yes # Enable RDP $Terminal = (Get-WmiObject -Class "Win32_TerminalServiceSetting" -Namespace root\cimv2\terminalservices).SetAllowTsConnections(1) return $Terminal } function enablePing() { #Create firewall manager object $FWM=new-object -com hnetcfg.fwmgr # Get current profile $pro=$fwm.LocalPolicy.CurrentProfile $pro.IcmpSettings.AllowInboundEchoRequest=$true } function addReadme($context) { $username = $context["USERNAME"] Copy-Item D:\README.txt C:\Users\$username\Desktop\README.txt" } # If folder context doesn't exist create it if (-not (Test-Path "c:\context\")) { New-Item "C:\context\" -type directory } # Execute script if( -not(Test-Path "c:\context\contextualized") -and (Test-Path "D:\context.sh")) { $context = @{} $context = getContext('D:\context.sh') addLocalUser($context) renameComputer($context) enableRemoteDesktop enablePing addReadme($context) Start-Sleep -s 30 configureNetwork($context) echo "contextualized" |Out-File ("c:\context\contextualized") restart-computer -force } ## Restart a second time to ensure network connection else if( -not(Test-Path "c:\context\contextualizedNetwork") -and (Test-Path "D:\context.sh")) { $context = @{} $context = getContext('D:\context.sh') configureNetwork($context) addReadme($context) echo "contextualizedNetwork" |Out-File ("c:\context\contextualizedNetwork") }
context.sh
Context.sh is the context file created by OpenNebula from the image template. It has several attributes, which are filled on every instantiation. The example below is of an instantiated VM. The files attribute indicates that ONE is going to build a context disk in drive D with that list of files. Hostname, IP, username and password can be modified and include variables such as $VMID.
CONTEXT=[ FILES="/opt/opennebula_shared/context-scripts/windows/startup.vbs /opt/opennebula_shared/context-scripts/windows/one-context.ps1 /opt/opennebula_shared/context-scripts/windows/unattend.xml /opt/opennebula_shared/context-scripts/windows/README.txt /opt/opennebula_shared/context-scripts/windows/SetupComplete.cmd", HOSTNAME=Win2008-681, IP_PUBLIC=192.168.1.1 PASSWORD=password, USERNAME=username]
README.txt
This text file is only for user integration, it can have a couple of rules when using the machine
Configuration rules ---------------------- - once logged in, change initial passwords - keep always copy of important data and execute regular backups (i.e. DB) - when the machine is not needed anymore, shut it down and ask the administrator to remove it Windows ---------------------- User:theuser Password:thepassword SQL Server ---------------------- User:theuser Password:thepassword
Sample files are available on wiki files.
Preparing Windows Images
The first step is to create a new image file to install windows. If you have QEMU installed, it is easy enough as running
qemu-img create -f qcow2 newimage.qcow2 30G
20GB should be enough for Windows 7 64-bit and 30GB suitable for Windows 2008 R2 64-bit, normal installation leaves about 10GB free for other programs you want to install.
To use the image, you can be assisted by Virt-Manager. Create a new machine, select the Windows ISO to install and the path of the just created image and run the machine.
*IMPORTANT - due to Windows compatibility problems, choose Virtio disk and e1000 network card - other hardware can be problematic and cause bluescreens*.
Sometimes Windows doesn't recognize the whole space from the qcow image. If you are unable to install with qcow file, just create a raw image
qemu-img create -f raw newimage.raw 30G
and after install convert it to qcow2:
qemu-img convert -O qcow2 newimage.raw newimage.qcow2
You can follow the whole process with Virt-manager through VNC.
After a clean install of a Windows OS on an image file, with all the hardware which will be replicated, it is necessary to do a few steps. If you do not want to do a new installation (i.e. you have lots of programs installed and configurations made), you must do a sysprep to wipe out all the personal and sensitive data.
Syspreping the system
There are many useful guides to sysprep a Windows machine, but we used this guide, http://theitbros.com/sysprep-a-windows-7-machine-%E2%80%93-start-to-finish, to execute it. But we'll try to shorten it a little bit.
You need: - install Windows® Automated Installation Kit (AIK) for Windows® 7 - ISO or DVD of Windows Installation
After that, run AIK, open the ISO and the file "\sources\install.wim" and choose all the features you want to customize, as locale, timezone, admin account and license key, among many others. Save and your XML is ready to go.
Copy or move your "unattend.xml" file to "C:\windows\system32\sysprep". Run a Command Prompt window with administrative priviledges and execute
"sysprep /generalize /oobe /shutdown /unattend:unattend.xml". Your system will now be cleaned up, prepared and shutdown after all done.
A sample file is available on wiki files, for Windows 2008 R2 64-bit.
Preparing the system
Before the machine is ready for template, please install whatever software you need for it and that can avoid a few dozens of hours in end-user installations. To ready the machine, you just need to go to Local Group Policy. Just go to Adminstrative Tools->Local Group Policy or simply hit Run->gpedit.msc. Go to the Local Computer Policy->Computer Configuration->Windows Settings->Scripts->Startup and right-click on Properties. Add a new script and write "D:\SetupComplete.cmd", the file doesn't exist yet but it won't complain. Hit OK and you're ready to go. Make sure there aren't no folders named "context" on C:\ and shutdown the machine.
Registering/activating Windows
Regardless the method you chose to prepare your Windows image, you'll have to register it and activate it. If you already have the image activated, made this manually or made it through the Sysprep you're done. If you don't have a single license key and want to use a volume license, register it a simple slmrg command:
slmgr.vbs /skms yourlicenseserver.com:port
After a successful communication and an ok feedback, you can activate it with:
slmgr.vbs /ato
And you're done!
Finalizing the image
After all these steps, we need to take a snapshot of the image and register it on OpenNebula (optional but recommended). To use the copy-on-write property, we'll use the created Windows image as a base image and work on another file. Now, this is a very important step. Although it enforces us to repeat the steps for each created qcow image, this step allows OpenNebula to continue to use any kind of image other than qcow. When following the official qcow manual (https://support.opennebula.pro/entries/348847-using-qcow-images), OpenNebula is somewhat limited when using qcow images.
qemu-img create -f qcow2 -b /opt/.../win2k8-sql08-vs10.qcow2 snapshot.qcow2
Create a image template "win2k8-sql08-vs10.one" for the snapshot:
NAME = "Win2k8" SOURCE = /opt/opennebula/var/golden-images/win2k8/snapshot.qcow2 TYPE = OS PUBLIC = YES DRIVER = qcow2 BUS = virtio DESCRIPTION = "Windows 2008 desktop for students."
And register it with
oneimg create win2k8-sql08-vs10.one
Creating an OpenNebula template
After we created our image, we need to build the ONE template for standard instantiation. Our template for Windows 2008 is:
CONTEXT=[ FILES="/home/oneadmin/.ssh/id_rsa.pub /opt/opennebula_shared/context-scripts/windows/startup.vbs /opt/opennebula_shared/context-scripts/windows/one-context.ps1 /opt/opennebula_shared/context-scripts/windows/unattend.xml /opt/opennebula_shared/context-scripts/windows/README.txt /opt/opennebula_shared/context-scripts/windows/SetupComplete.cmd", HOSTNAME=Win2008-$VMID, IP_PUBLIC="$NIC[IP, NETWORK=\"Aulas Network\"]", PASSWORD=thepassword, ROOT_PUBKEY=id_rsa.pub, USERNAME=theusername ] CPU=1 DISK=[ BUS=virtio, DRIVER=qcow2, READONLY=no, IMAGE_ID = 12, #(or "SOURCE=/opt/opennebula/var/golden-images/win2k8/snapshot.qcow2," if you didn't register the image) TARGET=vda, TYPE=disk ] FEATURES=[ ACPI=yes ] GRAPHICS=[ TYPE=vnc ] MEMORY=2048 NAME=Windows2008-SQL2008-VS2010 NIC=[ MODEL=e1000, NETWORK_ID=4 ] OS=[ ARCH=x86_64, BOOT=hd ] RAW=[ TYPE=kvm ]
It can be pasted on a new file "Windows2008.one" or created on the web browser on Sunstone, on section Templates->Advanced. Adapt your settings on the template and its done! You can start a new VM with the new template in 10s!
Files